summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2004-05-01 16:15:05 (UTC)
committer mickeyl <mickeyl>2004-05-01 16:15:05 (UTC)
commitfd2bbf9a09aa7a13bd8a43db351b9153e5a4b7ab (patch) (unidiff)
tree17e24a7acb78e995e53ec7127e2d20a834984706
parentd5abd7878f553f5ac0a41966b27f4c09389d3cfd (diff)
downloadopie-fd2bbf9a09aa7a13bd8a43db351b9153e5a4b7ab.zip
opie-fd2bbf9a09aa7a13bd8a43db351b9153e5a4b7ab.tar.gz
opie-fd2bbf9a09aa7a13bd8a43db351b9153e5a4b7ab.tar.bz2
- be really paranoid about wireless extension versions for compile time vs. run time
- register handlers for SIGSEGV and SIGBUG to emergency-close the capture file
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/wellenreiter/ChangeLog3
-rw-r--r--noncore/net/wellenreiter/TODO6
-rw-r--r--noncore/net/wellenreiter/gui/wellenreiter.cpp48
-rw-r--r--noncore/net/wellenreiter/gui/wellenreiter.h5
4 files changed, 56 insertions, 6 deletions
diff --git a/noncore/net/wellenreiter/ChangeLog b/noncore/net/wellenreiter/ChangeLog
index fdc8aa7..b59f9f9 100644
--- a/noncore/net/wellenreiter/ChangeLog
+++ b/noncore/net/wellenreiter/ChangeLog
@@ -1,66 +1,69 @@
1 2004-??-?? Michael Lauer <mickey@Vanille.de> 1 2004-??-?? Michael Lauer <mickey@Vanille.de>
2 2
3 * Registered a signal handler. We're now trying to gracefully exit and emergency close capture files.
4 This should allow reproducing failures.
5 * Added sanity check for compile time vs. run time Wireless Extension versions.
3 * Added sanity check isPresent(interface) before starting the engine. 6 * Added sanity check isPresent(interface) before starting the engine.
4 * Added a View submenu. Added actions to expand and collapse all items. 7 * Added a View submenu. Added actions to expand and collapse all items.
5 * Switched to a (hopefully) more reliable method reading from gpsd. 8 * Switched to a (hopefully) more reliable method reading from gpsd.
6 * Added parsing of named ProbeRequests. Display only-probed-yet SSIDs in a different network color. 9 * Added parsing of named ProbeRequests. Display only-probed-yet SSIDs in a different network color.
7 * Rewrote the simple actions on new {Network, Client, Station}. Besides playing a sound or 10 * Rewrote the simple actions on new {Network, Client, Station}. Besides playing a sound or
8 blinking a LED, a user customizable script can now be executed, if something has been 11 blinking a LED, a user customizable script can now be executed, if something has been
9 detected. This opens up many possibilities, i.e. a qcop to qpegps or exec'ing flite (speech). 12 detected. This opens up many possibilities, i.e. a qcop to qpegps or exec'ing flite (speech).
10 * Added decloaking of cloaked ESSIDs (length != 0, but essid[0] == \0). 13 * Added decloaking of cloaked ESSIDs (length != 0, but essid[0] == \0).
11 * Hided the 'Parse' Tab in the configuration window. Not functional now and may come later 14 * Hided the 'Parse' Tab in the configuration window. Not functional now and may come later
12 * Added parsing of control frames. Display stations sending them SSID "<unknown>" for now. 15 * Added parsing of control frames. Display stations sending them SSID "<unknown>" for now.
13 * Added command line option "-nocheck" to skip non-root and dhcp tests. 16 * Added command line option "-nocheck" to skip non-root and dhcp tests.
14 * Improved the speed of and user feedback during reading the manufacturer list. 17 * Improved the speed of and user feedback during reading the manufacturer list.
15 * GPS coordinates are now presented in the DMS (as opposed to decimal) format. 18 * GPS coordinates are now presented in the DMS (as opposed to decimal) format.
16 19
17 2003-12-18 Michael Lauer <mickey@Vanille.de> 20 2003-12-18 Michael Lauer <mickey@Vanille.de>
18 21
19 * Released as Version 1.0.2 (Development Snapshot) 22 * Released as Version 1.0.2 (Development Snapshot)
20 * Added automatic uploading of capture files to "The Capture Dump" site at 23 * Added automatic uploading of capture files to "The Capture Dump" site at
21 http://www.Vanille.de/projects/capturedump.spy 24 http://www.Vanille.de/projects/capturedump.spy
22 * Initial reading of the manufacturer database happens now in background 25 * Initial reading of the manufacturer database happens now in background
23 * Removed deprecated setMonitorMode() API ==> Use setMode( "monitor" ) now. 26 * Removed deprecated setMonitorMode() API ==> Use setMode( "monitor" ) now.
24 The monitor mode now tries to use the standard IW_MODE_MONITOR first. If that 27 The monitor mode now tries to use the standard IW_MODE_MONITOR first. If that
25 doesn't work, it falls back to using the proprietary iwpriv commands 28 doesn't work, it falls back to using the proprietary iwpriv commands
26 29
27 2003-11-30 Michael Lauer <mickey@Vanille.de> 30 2003-11-30 Michael Lauer <mickey@Vanille.de>
28 31
29 * Released as Version 1.0.1 (Development Snapshot) 32 * Released as Version 1.0.1 (Development Snapshot)
30 * Fixed ARP decoding for wired networks. 33 * Fixed ARP decoding for wired networks.
31 Interestingly, 802.11 encapsulates these in IP packets, while wired ethernet just tags the type_of_protocol. 34 Interestingly, 802.11 encapsulates these in IP packets, while wired ethernet just tags the type_of_protocol.
32 * Added reading GPS data from a gps daemon. 35 * Added reading GPS data from a gps daemon.
33 * Started preparations for utilizing Wellenreiter II in wired networks. 36 * Started preparations for utilizing Wellenreiter II in wired networks.
34 * Implemented persistant configuration interface and retriggerable auto detection. 37 * Implemented persistant configuration interface and retriggerable auto detection.
35 * Added QCOP interface for talking to opie-networksettings. 38 * Added QCOP interface for talking to opie-networksettings.
36 * Added parsing of DHCP packets and detecting DHCP servers. 39 * Added parsing of DHCP packets and detecting DHCP servers.
37 * Overhauled the configuration window and started with the customizable event system. 40 * Overhauled the configuration window and started with the customizable event system.
38 * Added disabling the screensaver. 41 * Added disabling the screensaver.
39 * Added automatic opening and scrolling to the network tree if a new station appears. 42 * Added automatic opening and scrolling to the network tree if a new station appears.
40 43
41 2003-05-10 Michael Lauer <mickey@Vanille.de> 44 2003-05-10 Michael Lauer <mickey@Vanille.de>
42 45
43 * Released as Version 1.0 (Stable) 46 * Released as Version 1.0 (Stable)
44 * Added restarting the dhcp client if having killed it before. 47 * Added restarting the dhcp client if having killed it before.
45 * Decouple dump files from live capture to shift control over 'what' is dumped to applications. 48 * Decouple dump files from live capture to shift control over 'what' is dumped to applications.
46 49
47 2003-05-05 Michael Lauer <mickey@Vanille.de> 50 2003-05-05 Michael Lauer <mickey@Vanille.de>
48 51
49 * Released as Version 1.0-RC1 (Release Candidate) 52 * Released as Version 1.0-RC1 (Release Candidate)
50 * Fixed rare segfaults while sniffing and operating the GUI simultaenously. 53 * Fixed rare segfaults while sniffing and operating the GUI simultaenously.
51 * Parse more data packets and detect more participating stations. 54 * Parse more data packets and detect more participating stations.
52 * Added live graph window showing the signal strength on all channels. 55 * Added live graph window showing the signal strength on all channels.
53 * Added parsing ARP packets and identifying IP addresses of participating stations. 56 * Added parsing ARP packets and identifying IP addresses of participating stations.
54 * Added parsing with optionally enabled PRISM headers (signal strength). 57 * Added parsing with optionally enabled PRISM headers (signal strength).
55 58
56 2003-04-12 Michael Lauer <mickey@Vanille.de> 59 2003-04-12 Michael Lauer <mickey@Vanille.de>
57 60
58 * Released as Version 1.0 (Beta) 61 * Released as Version 1.0 (Beta)
59 * GUI enhancements in the Menubar and the Toolbar. 62 * GUI enhancements in the Menubar and the Toolbar.
60 * Improved keyboard handling. 63 * Improved keyboard handling.
61 * Added sanity checks for running Wellenreiter II as non-root or with dhcp clients in the background. 64 * Added sanity checks for running Wellenreiter II as non-root or with dhcp clients in the background.
62 * Add writing and replaying of libpcap compatible capture files. 65 * Add writing and replaying of libpcap compatible capture files.
63 66
64 2003-04-08 Michael Lauer <mickey@Vanille.de> 67 2003-04-08 Michael Lauer <mickey@Vanille.de>
65 68
66 * Released as Version 0.2 (Alpha) 69 * Released as Version 0.2 (Alpha)
diff --git a/noncore/net/wellenreiter/TODO b/noncore/net/wellenreiter/TODO
index 0640d23..f0a193d 100644
--- a/noncore/net/wellenreiter/TODO
+++ b/noncore/net/wellenreiter/TODO
@@ -1,77 +1,75 @@
1/************************************************************************ 1/************************************************************************
2/* W e l l e n r e i t e r I I 2/* W e l l e n r e i t e r I I
3/* =============================== 3/* ===============================
4/* 4/*
5/* Version: 1.0.2 5/* Version: 1.0.2
6/************************************************************************ 6/************************************************************************
7 7
8---------------------------------------------------- 8----------------------------------------------------
9 Ideas as of Wellenreiter II / April 2004 9 Ideas as of Wellenreiter II / April 2004
10---------------------------------------------------- 10----------------------------------------------------
11 11
12-------- 12--------
13 BUILD 13 BUILD
14-------- 14--------
15 15
16- fix building against X11 again 16- fix building against X11 again
17 17
18-------- 18--------
19 ENGINE 19 ENGINE
20-------- 20--------
21 21
22- enable multiple packet sources 22- enable multiple packet sources
23 - infrared 23 - infrared
24 - bluetooth 24 - bluetooth
25 - usb? 25 - usb
26 26
27- define packet structure in a metalanguage and generate 27- define packet structure in a metalanguage and generate
28 the actual parsing code (hmmm) 28 the actual parsing code (hmmm)
29 29
30- pester the ethereal folks to settle for an application independant 30- pester the ethereal folks to settle for an application independant
31 packet dissection framework... (unlikely) 31 packet dissection framework... (unlikely)
32 32
33- adaptive hopping scheme ! 33- adaptive hopping scheme !
34 34
35- gather interface capabilities 35- gather interface capabilities
36 36
37- enable sniffing in wired networks 37- enable sniffing in wired networks
38 38
39- fix autodetection (interface name) 39- fix autodetection (the interface name is not selected correctly)
40 40
41- use ethtool IOCTLs (if present) 41- use ethtool IOCTLs (if present)
42 42
43--------- 43---------
44 UI 44 UI
45--------- 45---------
46 46
47- display interface capabilities (or rewrite networksettings?) 47- display interface capabilities (or rewrite networksettings?)
48 48
49- distinguish wireless bridges (WDS traffic) 49- distinguish wireless bridges (WDS traffic)
50 50
51- add configuration for scrollback buffer in hex window and log window 51- add configuration for scrollback buffer in hex window and log window
52 52
53- revamp hex window, make it more sophisticated than just a QMultiLineEdit 53- revamp hex window, make it more sophisticated than just a QMultiLineEdit
54 - tree view 54 - tree view
55 55
56- beep over headphone / customizable 56- beep over headphone / customizable
57 57
58- count/display number of wireless networks / APs since last start/stop 58- count/display number of wireless networks / APs since last start/stop
59 59
60--------- 60---------
61 FILES 61 FILES
62--------- 62---------
63 63
64- write kismet-like .network format and format to be importable into AutoRoute 64- write kismet-like .network format and format to be importable into AutoRoute
65 65
66- implement beacon stripping (the first beacon is enough to detect a 66- implement beacon stripping (the first beacon is enough to detect a
67 new network - further beacons just blow up the capture file) 67 new network - further beacons just blow up the capture file)
68 68
69- write wi-scan format like that: 69- write wi-scan format like that:
70 # $Creator: Wellenreiter II Version 1.0.2 70 # $Creator: Wellenreiter II Version 1.0.2
71 # $Format: wi-scan 71 # $Format: wi-scan
72 # Latitude Longitude ( SSID ) Type ( BSSID ) Time (GMT) [ SNR Sig Noise ] 72 # Latitude Longitude ( SSID ) Type ( BSSID ) Time (GMT) [ SNR Sig Noise ]
73 # $DateGMT: 2004-02-07 73 # $DateGMT: 2004-02-07
74 N 41.1008009 W 8.3893034 ( Porceven ) BBS ( 00:a0:f8:41:91:63 ) 22:32:39 (GMT) [ 21 177 156 ] 74 N 41.1008009 W 8.3893034 ( Porceven ) BBS ( 00:a0:f8:41:91:63 ) 22:32:39 (GMT) [ 21 177 156 ]
75 75
76- add SIGSEGV handler for emergency closing the capture file etc.
77
diff --git a/noncore/net/wellenreiter/gui/wellenreiter.cpp b/noncore/net/wellenreiter/gui/wellenreiter.cpp
index 40cd105..12b3978 100644
--- a/noncore/net/wellenreiter/gui/wellenreiter.cpp
+++ b/noncore/net/wellenreiter/gui/wellenreiter.cpp
@@ -1,169 +1,203 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2002-2004 Michael 'Mickey' Lauer. All rights reserved. 2** Copyright (C) 2002-2004 Michael 'Mickey' Lauer. All rights reserved.
3** 3**
4** This file may be distributed and/or modified under the terms of the 4** This file may be distributed and/or modified under the terms of the
5** GNU General Public License version 2 as published by the Free Software 5** GNU General Public License version 2 as published by the Free Software
6** Foundation and appearing in the file LICENSE.GPL included in the 6** Foundation and appearing in the file LICENSE.GPL included in the
7** packaging of this file. 7** packaging of this file.
8** 8**
9** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 9** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 10** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11** 11**
12***********************************************************************/ 12***********************************************************************/
13 13
14#include "gps.h" 14#include "gps.h"
15#include "wellenreiter.h" 15#include "wellenreiter.h"
16#include "scanlist.h" 16#include "scanlist.h"
17#include "logwindow.h" 17#include "logwindow.h"
18#include "packetview.h" 18#include "packetview.h"
19#include "configwindow.h" 19#include "configwindow.h"
20#include "statwindow.h" 20#include "statwindow.h"
21#include "graphwindow.h" 21#include "graphwindow.h"
22#include "protolistview.h" 22#include "protolistview.h"
23 23
24/* OPIE */ 24/* OPIE */
25#ifdef QWS 25#ifdef QWS
26#include <opie2/oapplication.h> 26#include <opie2/oapplication.h>
27#include <opie2/odebug.h> 27#include <opie2/odebug.h>
28#include <opie2/odevice.h> 28#include <opie2/odevice.h>
29#else 29#else
30#include <qapplication.h> 30#include <qapplication.h>
31#endif 31#endif
32#include <opie2/omanufacturerdb.h> 32#include <opie2/omanufacturerdb.h>
33#include <opie2/onetwork.h> 33#include <opie2/onetwork.h>
34#include <opie2/opcap.h> 34#include <opie2/opcap.h>
35#include <qpe/qcopenvelope_qws.h> 35#include <qpe/qcopenvelope_qws.h>
36using namespace Opie::Core; 36using namespace Opie::Core;
37using namespace Opie::Net; 37using namespace Opie::Net;
38using namespace Opie::Ui; 38using namespace Opie::Ui;
39 39
40/* QT */ 40/* QT */
41#include <qcheckbox.h> 41#include <qcheckbox.h>
42#include <qcombobox.h> 42#include <qcombobox.h>
43#include <qdatetime.h> 43#include <qdatetime.h>
44#include <qpushbutton.h> 44#include <qpushbutton.h>
45#include <qlineedit.h> 45#include <qlineedit.h>
46#include <qmessagebox.h> 46#include <qmessagebox.h>
47#include <qobjectlist.h> 47#include <qobjectlist.h>
48#include <qregexp.h> 48#include <qregexp.h>
49#include <qspinbox.h> 49#include <qspinbox.h>
50#include <qtimer.h> 50#include <qtimer.h>
51#include <qtoolbutton.h> 51#include <qtoolbutton.h>
52#include <qmainwindow.h> 52#include <qmainwindow.h>
53 53
54/* STD */ 54/* STD */
55#include <assert.h> 55#include <assert.h>
56#include <errno.h> 56#include <errno.h>
57#include <unistd.h> 57#include <unistd.h>
58#include <string.h> 58#include <string.h>
59#include <sys/types.h> 59#include <sys/types.h>
60#include <stdlib.h> 60#include <stdlib.h>
61#include <signal.h>
62
63Wellenreiter* Wellenreiter::instance = 0;
61 64
62Wellenreiter::Wellenreiter( QWidget* parent ) 65Wellenreiter::Wellenreiter( QWidget* parent )
63 : WellenreiterBase( parent, 0, 0 ), 66 : WellenreiterBase( parent, 0, 0 ),
64 sniffing( false ), iface( 0 ), configwindow( 0 ) 67 sniffing( false ), iface( 0 ), configwindow( 0 )
65{ 68{
66 69
67 logwindow->log( "(i) Wellenreiter has been started." ); 70 logwindow->log( "(i) Wellenreiter has been started." );
68 71
69 // 72 //
70 // detect operating system 73 // detect operating system
71 // 74 //
72 75
73 #ifdef QWS 76 #ifdef QWS
74 QString sys; 77 QString sys;
75 sys.sprintf( "(i) Running on '%s'.", (const char*) ODevice::inst()->systemString() ); 78 sys.sprintf( "(i) Running on '%s'.", (const char*) ODevice::inst()->systemString() );
76 _system = ODevice::inst()->system(); 79 _system = ODevice::inst()->system();
77 logwindow->log( sys ); 80 logwindow->log( sys );
78 #endif 81 #endif
79 82
80 netview->setColumnWidthMode( 1, QListView::Manual ); 83 netview->setColumnWidthMode( 1, QListView::Manual );
81 connect( netview, SIGNAL( joinNetwork(const QString&,const QString&,int,const QString&) ), 84 connect( netview, SIGNAL( joinNetwork(const QString&,const QString&,int,const QString&) ),
82 this, SLOT( joinNetwork(const QString&,const QString&,int,const QString&) ) ); 85 this, SLOT( joinNetwork(const QString&,const QString&,int,const QString&) ) );
83 pcap = new OPacketCapturer(); 86 pcap = new OPacketCapturer();
84 pcap->setAutoDelete( false ); 87 pcap->setAutoDelete( false );
85 88
86 gps = new GPS( this ); 89 gps = new GPS( this );
87 90
88 QTimer::singleShot( 1000, this, SLOT( initialTimer() ) ); 91 QTimer::singleShot( 1000, this, SLOT( initialTimer() ) );
89 92
93 registerSignalHandler();
90} 94}
91 95
92 96
93Wellenreiter::~Wellenreiter() 97Wellenreiter::~Wellenreiter()
94{ 98{
95 delete pcap; 99 delete pcap;
100 //unregisterSignalHandler();
96} 101}
97 102
98 103
99void Wellenreiter::initialTimer() 104void Wellenreiter::initialTimer()
100{ 105{
101 odebug << "Wellenreiter::preloading manufacturer database..." << oendl; 106 odebug << "preloading manufacturer database..." << oendl;
102 OManufacturerDB::instance(); 107 OManufacturerDB::instance();
103} 108}
104 109
105 110
111void Wellenreiter::signalHandler( int sig )
112{
113 oerr << "Aye! Received SIGSEGV or SIGBUS! Trying to exit gracefully..." << oendl;
114 if ( Wellenreiter::instance->sniffing )
115 {
116 Wellenreiter::instance->pcap->close();
117 Wellenreiter::instance->stopClicked();
118 }
119 oerr << "Phew. Seemed to work." << oendl;
120 ::exit( -1 );
121}
122
123
124void Wellenreiter::registerSignalHandler()
125{
126 Wellenreiter::instance = this;
127 struct sigaction action;
128
129 action.sa_handler = Wellenreiter::signalHandler;
130 if (sigemptyset(&action.sa_mask))
131 oerr << "sigemptyset() failure:" << strerror( errno ) << oendl;
132 if (sigaction(SIGSEGV, &action, NULL))
133 oerr << "can't set up a signal handler for SIGSEGV:" << strerror( errno ) << oendl;
134 if (sigaction(SIGBUS, &action, NULL))
135 oerr << "can't set up a signal handler for SIGBUS:" << strerror( errno ) << oendl;
136 odebug << "signal handlers setup." << oendl;
137}
138
139
106void Wellenreiter::setConfigWindow( WellenreiterConfigWindow* cw ) 140void Wellenreiter::setConfigWindow( WellenreiterConfigWindow* cw )
107{ 141{
108 configwindow = cw; 142 configwindow = cw;
109} 143}
110 144
111 145
112void Wellenreiter::channelHopped(int c) 146void Wellenreiter::channelHopped(int c)
113{ 147{
114 QString title = "Wellenreiter II -scan- ["; 148 QString title = "Wellenreiter II -scan- [";
115 QString left; 149 QString left;
116 if ( c > 1 ) left.fill( '.', c-1 ); 150 if ( c > 1 ) left.fill( '.', c-1 );
117 title.append( left ); 151 title.append( left );
118 title.append( '|' ); 152 title.append( '|' );
119 if ( c < iface->channels() ) 153 if ( c < iface->channels() )
120 { 154 {
121 QString right; 155 QString right;
122 right.fill( '.', iface->channels()-c ); 156 right.fill( '.', iface->channels()-c );
123 title.append( right ); 157 title.append( right );
124 } 158 }
125 title.append( "]" ); 159 title.append( "]" );
126 //title.append( QString().sprintf( " %02d", c ) ); 160 //title.append( QString().sprintf( " %02d", c ) );
127 assert( parent() ); 161 assert( parent() );
128 ( (QMainWindow*) parent() )->setCaption( title ); 162 ( (QMainWindow*) parent() )->setCaption( title );
129} 163}
130 164
131 165
132void Wellenreiter::handleNotification( OPacket* p ) 166void Wellenreiter::handleNotification( OPacket* p )
133{ 167{
134 QObjectList* l = p->queryList(); 168 QObjectList* l = p->queryList();
135 QObjectListIt it( *l ); 169 QObjectListIt it( *l );
136 QObject* o; 170 QObject* o;
137 171
138 while ( (o = it.current()) != 0 ) 172 while ( (o = it.current()) != 0 )
139 { 173 {
140 QString name = it.current()->name(); 174 QString name = it.current()->name();
141 if ( configwindow->parsePackets->isProtocolChecked( name ) ) 175 if ( configwindow->parsePackets->isProtocolChecked( name ) )
142 { 176 {
143 QString action = configwindow->parsePackets->protocolAction( name ); 177 QString action = configwindow->parsePackets->protocolAction( name );
144 odebug << "parsePacket-action for '" << (const char*) name << "' seems to be '" << action << "'" << oendl; 178 odebug << "parsePacket-action for '" << (const char*) name << "' seems to be '" << action << "'" << oendl;
145 doAction( action, name, p ); 179 doAction( action, name, p );
146 } 180 }
147 else 181 else
148 { 182 {
149 odebug << "protocol '" << name << "' not checked in parsePackets." << oendl; 183 odebug << "protocol '" << name << "' not checked in parsePackets." << oendl;
150 } 184 }
151 ++it; 185 ++it;
152 } 186 }
153} 187}
154 188
155 189
156void Wellenreiter::handleManagementFrame( OPacket* p, OWaveLanManagementPacket* manage ) 190void Wellenreiter::handleManagementFrame( OPacket* p, OWaveLanManagementPacket* manage )
157{ 191{
158 if ( manage->managementType() == "Beacon" ) handleManagementFrameBeacon( p, manage ); 192 if ( manage->managementType() == "Beacon" ) handleManagementFrameBeacon( p, manage );
159 else if ( manage->managementType() == "ProbeRequest" ) handleManagementFrameProbeRequest( p, manage ); 193 else if ( manage->managementType() == "ProbeRequest" ) handleManagementFrameProbeRequest( p, manage );
160 else if ( manage->managementType() == "ProbeResponse" ) handleManagementFrameProbeResponse( p, manage ); 194 else if ( manage->managementType() == "ProbeResponse" ) handleManagementFrameProbeResponse( p, manage );
161 else owarn << "Wellenreiter::handleManagementFrame(): '" << manage->managementType() << "' - please handle me!" << oendl; 195 else owarn << "Wellenreiter::handleManagementFrame(): '" << manage->managementType() << "' - please handle me!" << oendl;
162} 196}
163 197
164 198
165void Wellenreiter::handleManagementFrameProbeRequest( OPacket* p, OWaveLanManagementPacket* request ) 199void Wellenreiter::handleManagementFrameProbeRequest( OPacket* p, OWaveLanManagementPacket* request )
166{ 200{
167 OWaveLanManagementSSID* ssid = static_cast<OWaveLanManagementSSID*>( p->child( "802.11 SSID" ) ); 201 OWaveLanManagementSSID* ssid = static_cast<OWaveLanManagementSSID*>( p->child( "802.11 SSID" ) );
168 QString essid = ssid ? ssid->ID( true /* decloak */ ) : QString("<unknown>"); 202 QString essid = ssid ? ssid->ID( true /* decloak */ ) : QString("<unknown>");
169 OWaveLanManagementDS* ds = static_cast<OWaveLanManagementDS*>( p->child( "802.11 DS" ) ); 203 OWaveLanManagementDS* ds = static_cast<OWaveLanManagementDS*>( p->child( "802.11 DS" ) );
@@ -441,158 +475,168 @@ void Wellenreiter::receivePacket( OPacket* p )
441} 475}
442 476
443 477
444void Wellenreiter::stopClicked() 478void Wellenreiter::stopClicked()
445{ 479{
446 if ( iface ) 480 if ( iface )
447 { 481 {
448 disconnect( SIGNAL( receivedPacket(Opie::Net::OPacket*) ), this, SLOT( receivePacket(Opie::Net::OPacket*) ) ); 482 disconnect( SIGNAL( receivedPacket(Opie::Net::OPacket*) ), this, SLOT( receivePacket(Opie::Net::OPacket*) ) );
449 disconnect( SIGNAL( hopped(int) ), this, SLOT( channelHopped(int) ) ); 483 disconnect( SIGNAL( hopped(int) ), this, SLOT( channelHopped(int) ) );
450 iface->setChannelHopping(); // stop hopping channels 484 iface->setChannelHopping(); // stop hopping channels
451 } 485 }
452 else 486 else
453 killTimers(); 487 killTimers();
454 488
455 pcap->close(); 489 pcap->close();
456 sniffing = false; 490 sniffing = false;
457 491
458 if ( iface ) 492 if ( iface )
459 { 493 {
460 // switch off monitor mode 494 // switch off monitor mode
461 iface->setMode( "managed" ); 495 iface->setMode( "managed" );
462 // switch off promisc flag 496 // switch off promisc flag
463 iface->setPromiscuousMode( false ); 497 iface->setPromiscuousMode( false );
464 498
465 system( "cardctl reset; sleep 1" ); //FIXME: Use OProcess 499 system( "cardctl reset; sleep 1" ); //FIXME: Use OProcess
466 } 500 }
467 501
468 logwindow->log( "(i) Stopped Scanning." ); 502 logwindow->log( "(i) Stopped Scanning." );
469 assert( parent() ); 503 assert( parent() );
470 ( (QMainWindow*) parent() )->setCaption( "Wellenreiter II" ); 504 ( (QMainWindow*) parent() )->setCaption( "Wellenreiter II" );
471 505
472 // message the user 506 // message the user
473 QMessageBox::information( this, "Wellenreiter II", 507 QMessageBox::information( this, "Wellenreiter II",
474 tr( "Your wireless card\nshould now be usable again." ) ); 508 tr( "Your wireless card\nshould now be usable again." ) );
475 509
476 sniffing = false; 510 sniffing = false;
477 emit( stoppedSniffing() ); 511 emit( stoppedSniffing() );
478 512
479 #ifdef QWS 513 #ifdef QWS
480 if ( WellenreiterConfigWindow::instance()->disablePM->isChecked() ) 514 if ( WellenreiterConfigWindow::instance()->disablePM->isChecked() )
481 { 515 {
482 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 516 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
483 } 517 }
484 #else 518 #else
485 #warning FIXME: setScreenSaverMode is not operational on the X11 build 519 #warning FIXME: setScreenSaverMode is not operational on the X11 build
486 #endif 520 #endif
487 521
488 // print out statistics 522 // print out statistics
489 for( QMap<QString,int>::ConstIterator it = pcap->statistics().begin(); it != pcap->statistics().end(); ++it ) 523 for( QMap<QString,int>::ConstIterator it = pcap->statistics().begin(); it != pcap->statistics().end(); ++it )
490 statwindow->updateCounter( it.key(), it.data() ); 524 statwindow->updateCounter( it.key(), it.data() );
491} 525}
492 526
493 527
494void Wellenreiter::startClicked() 528void Wellenreiter::startClicked()
495{ 529{
496 // get configuration from config window 530 // get configuration from config window
497 531
498 const QString& interface = configwindow->interfaceName->currentText(); 532 const QString& interface = configwindow->interfaceName->currentText();
499 const int cardtype = configwindow->driverType(); 533 const int cardtype = configwindow->driverType();
500 const int interval = configwindow->hoppingInterval(); 534 const int interval = configwindow->hoppingInterval();
501 535
502 if ( ( interface == "" ) || ( cardtype == 0 ) ) 536 if ( ( interface == "" ) || ( cardtype == 0 ) )
503 { 537 {
504 QMessageBox::information( this, "Wellenreiter II", 538 QMessageBox::information( this, "Wellenreiter II",
505 tr( "Your device is not\nproperly configured. Please reconfigure!" ) ); 539 tr( "No device configured.\nPlease reconfigure!" ) );
506 return; 540 return;
507 } 541 }
508 542
509 // configure device 543 // configure device
510 ONetwork* net = ONetwork::instance(); 544 ONetwork* net = ONetwork::instance();
511 545
512 // TODO: check if interface is wireless and support sniffing for non-wireless interfaces 546 // TODO: check if interface is wireless and support sniffing for non-wireless interfaces
513 547
514 if ( cardtype != DEVTYPE_FILE ) 548 if ( cardtype != DEVTYPE_FILE )
515 { 549 {
516 550
517 if ( !net->isPresent( interface ) ) 551 if ( !net->isPresent( interface ) )
518 { 552 {
519 QMessageBox::information( this, "Wellenreiter II", 553 QMessageBox::information( this, "Wellenreiter II",
520 tr( "The configured device (%1)\nis not available on this system\n. Please reconfigure!" ).arg( interface ) ); 554 tr( "The configured device (%1)\nis not available on this system\n. Please reconfigure!" ).arg( interface ) );
521 return; 555 return;
522 } 556 }
523 557
524 iface = static_cast<OWirelessNetworkInterface*>(net->interface( interface )); // fails if network is not wireless! 558 iface = static_cast<OWirelessNetworkInterface*>(net->interface( interface )); // fails if network is not wireless!
525 assert( iface ); 559 assert( iface );
526 560
527 // bring device UP 561 // bring device UP
528 iface->setUp( true ); 562 iface->setUp( true );
529 if ( !iface->isUp() ) 563 if ( !iface->isUp() )
530 { 564 {
531 QMessageBox::warning( this, "Wellenreiter II", 565 QMessageBox::warning( this, "Wellenreiter II",
532 tr( "Can't bring interface '%1' up:\n" ).arg( iface->name() ) + strerror( errno ) ); 566 tr( "Can't bring interface '%1' up:\n" ).arg( iface->name() ) + strerror( errno ) );
533 return; 567 return;
534 } 568 }
569
570 // check if wireless extension version matches
571 if ( ONetwork::wirelessExtensionCompileVersion() != iface->wirelessExtensionDriverVersion() )
572 {
573 QMessageBox::critical( this, "Wellenreiter II", tr( "<p>The Wireless Extension Versions<br>are not matching!<p>"
574 " Wellenreiter II : WE V%1<br>Interface driver: WE V%2" )
575 .arg( QString::number( ONetwork::wirelessExtensionCompileVersion() ) )
576 .arg( QString::number( iface->wirelessExtensionDriverVersion() ) ) );
577 return;
578 }
535 } 579 }
536 // set monitor mode 580 // set monitor mode
537 bool usePrism = configwindow->usePrismHeader(); 581 bool usePrism = configwindow->usePrismHeader();
538 582
539 switch ( cardtype ) 583 switch ( cardtype )
540 { 584 {
541 case DEVTYPE_CISCO: iface->setMonitoring( new OCiscoMonitoringInterface( iface, usePrism ) ); break; 585 case DEVTYPE_CISCO: iface->setMonitoring( new OCiscoMonitoringInterface( iface, usePrism ) ); break;
542 case DEVTYPE_WLAN_NG: iface->setMonitoring( new OWlanNGMonitoringInterface( iface, usePrism ) ); break; 586 case DEVTYPE_WLAN_NG: iface->setMonitoring( new OWlanNGMonitoringInterface( iface, usePrism ) ); break;
543 case DEVTYPE_HOSTAP: iface->setMonitoring( new OHostAPMonitoringInterface( iface, usePrism ) ); break; 587 case DEVTYPE_HOSTAP: iface->setMonitoring( new OHostAPMonitoringInterface( iface, usePrism ) ); break;
544 case DEVTYPE_ORINOCO: iface->setMonitoring( new OOrinocoMonitoringInterface( iface, usePrism ) ); break; 588 case DEVTYPE_ORINOCO: iface->setMonitoring( new OOrinocoMonitoringInterface( iface, usePrism ) ); break;
545 case DEVTYPE_MANUAL: QMessageBox::information( this, "Wellenreiter II", tr( "Bring your device into\nmonitor mode now." ) ); break; 589 case DEVTYPE_MANUAL: QMessageBox::information( this, "Wellenreiter II", tr( "Bring your device into\nmonitor mode now." ) ); break;
546 case DEVTYPE_FILE: odebug << "Wellenreiter: Capturing from file '" << interface << "'" << oendl; break; 590 case DEVTYPE_FILE: odebug << "Wellenreiter: Capturing from file '" << interface << "'" << oendl; break;
547 default: assert( 0 ); // shouldn't reach this 591 default: assert( 0 ); // shouldn't reach this
548 } 592 }
549 593
550 // switch device into monitor mode 594 // switch device into monitor mode
551 if ( cardtype < DEVTYPE_FILE ) 595 if ( cardtype < DEVTYPE_FILE )
552 { 596 {
553 if ( cardtype != DEVTYPE_MANUAL ) 597 if ( cardtype != DEVTYPE_MANUAL )
554 iface->setMode( "monitor" ); 598 iface->setMode( "monitor" );
555 if ( iface->mode() != "monitor" ) 599 if ( iface->mode() != "monitor" )
556 { 600 {
557 if ( QMessageBox::warning( this, "Wellenreiter II", 601 if ( QMessageBox::warning( this, "Wellenreiter II",
558 tr( "Can't set interface '%1'\ninto monitor mode:\n" ).arg( iface->name() ) + strerror( errno ) + 602 tr( "Can't set interface '%1'\ninto monitor mode:\n" ).arg( iface->name() ) + strerror( errno ) +
559 tr( "\nContinue with limited functionality?" ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No ) 603 tr( "\nContinue with limited functionality?" ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
560 return; 604 return;
561 } 605 }
562 } 606 }
563 607
564 // open GPS device 608 // open GPS device
565 if ( configwindow->enableGPS->isChecked() ) 609 if ( configwindow->enableGPS->isChecked() )
566 { 610 {
567 odebug << "Wellenreiter:GPS enabled @ " << configwindow->gpsdHost->currentText() << ":" << configwindow->gpsdPort->value() << "" << oendl; 611 odebug << "Wellenreiter:GPS enabled @ " << configwindow->gpsdHost->currentText() << ":" << configwindow->gpsdPort->value() << "" << oendl;
568 gps->open( configwindow->gpsdHost->currentText(), configwindow->gpsdPort->value() ); 612 gps->open( configwindow->gpsdHost->currentText(), configwindow->gpsdPort->value() );
569 } 613 }
570 614
571 // open pcap and start sniffing 615 // open pcap and start sniffing
572 616
573 if ( configwindow->writeCaptureFile->isChecked() ) // write to a user specified capture file? 617 if ( configwindow->writeCaptureFile->isChecked() ) // write to a user specified capture file?
574 { 618 {
575 dumpname = configwindow->captureFileName->text(); 619 dumpname = configwindow->captureFileName->text();
576 if ( dumpname.isEmpty() ) dumpname = "captureFile"; 620 if ( dumpname.isEmpty() ) dumpname = "captureFile";
577 dumpname.append( '-' ); 621 dumpname.append( '-' );
578 dumpname.append( QTime::currentTime().toString().replace( QRegExp( ":" ), "-" ) ); 622 dumpname.append( QTime::currentTime().toString().replace( QRegExp( ":" ), "-" ) );
579 dumpname.append( ".wellenreiter" ); 623 dumpname.append( ".wellenreiter" );
580 } 624 }
581 else // write it anyway ;) 625 else // write it anyway ;)
582 { 626 {
583 dumpname = "/var/log/dump.wellenreiter"; 627 dumpname = "/var/log/dump.wellenreiter";
584 } 628 }
585 629
586 if ( cardtype != DEVTYPE_FILE ) 630 if ( cardtype != DEVTYPE_FILE )
587 pcap->open( interface ); 631 pcap->open( interface );
588 else 632 else
589 pcap->openCaptureFile( interface ); 633 pcap->openCaptureFile( interface );
590 634
591 odebug << "Wellenreiter:: dumping to " << dumpname << "" << oendl; 635 odebug << "Wellenreiter:: dumping to " << dumpname << "" << oendl;
592 pcap->openDumpFile( dumpname ); 636 pcap->openDumpFile( dumpname );
593 637
594 if ( !pcap->isOpen() ) 638 if ( !pcap->isOpen() )
595 { 639 {
596 QMessageBox::warning( this, "Wellenreiter II", tr( "Can't open packet capturer for\n'%1':\n" ).arg( 640 QMessageBox::warning( this, "Wellenreiter II", tr( "Can't open packet capturer for\n'%1':\n" ).arg(
597 cardtype == DEVTYPE_FILE ? (const char*) interface : iface->name() ) + QString(strerror( errno ) )); 641 cardtype == DEVTYPE_FILE ? (const char*) interface : iface->name() ) + QString(strerror( errno ) ));
598 return; 642 return;
diff --git a/noncore/net/wellenreiter/gui/wellenreiter.h b/noncore/net/wellenreiter/gui/wellenreiter.h
index f609ef4..32e5690 100644
--- a/noncore/net/wellenreiter/gui/wellenreiter.h
+++ b/noncore/net/wellenreiter/gui/wellenreiter.h
@@ -1,107 +1,112 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2002-2004 Michael 'Mickey' Lauer. All rights reserved. 2** Copyright (C) 2002-2004 Michael 'Mickey' Lauer. All rights reserved.
3** 3**
4** This file may be distributed and/or modified under the terms of the 4** This file may be distributed and/or modified under the terms of the
5** GNU General Public License version 2 as published by the Free Software 5** GNU General Public License version 2 as published by the Free Software
6** Foundation and appearing in the file LICENSE.GPL included in the 6** Foundation and appearing in the file LICENSE.GPL included in the
7** packaging of this file. 7** packaging of this file.
8** 8**
9** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 9** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 10** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11** 11**
12**********************************************************************/ 12**********************************************************************/
13 13
14#ifndef WELLENREITER_H 14#ifndef WELLENREITER_H
15#define WELLENREITER_H 15#define WELLENREITER_H
16 16
17#include "wellenreiterbase.h" 17#include "wellenreiterbase.h"
18 18
19#ifdef QWS 19#ifdef QWS
20#include <opie2/odevice.h> 20#include <opie2/odevice.h>
21#endif 21#endif
22 22
23#include <signal.h>
24
23class QTimerEvent; 25class QTimerEvent;
24class QPixmap; 26class QPixmap;
25namespace Opie {namespace Net {class OPacket;}} 27namespace Opie {namespace Net {class OPacket;}}
26namespace Opie {namespace Net {class OWaveLanManagementPacket;}} 28namespace Opie {namespace Net {class OWaveLanManagementPacket;}}
27namespace Opie {namespace Net {class OWaveLanControlPacket;}} 29namespace Opie {namespace Net {class OWaveLanControlPacket;}}
28namespace Opie {namespace Net {class OWaveLanDataPacket;}} 30namespace Opie {namespace Net {class OWaveLanDataPacket;}}
29namespace Opie {namespace Net {class OEthernetPacket;}} 31namespace Opie {namespace Net {class OEthernetPacket;}}
30namespace Opie {namespace Net {class OARPPacket;}} 32namespace Opie {namespace Net {class OARPPacket;}}
31namespace Opie {namespace Net {class OMacAddress;}} 33namespace Opie {namespace Net {class OMacAddress;}}
32namespace Opie {namespace Net {class OIPPacket;}} 34namespace Opie {namespace Net {class OIPPacket;}}
33namespace Opie {namespace Net {class OPacket;}} 35namespace Opie {namespace Net {class OPacket;}}
34namespace Opie {namespace Net {class OWirelessNetworkInterface;}} 36namespace Opie {namespace Net {class OWirelessNetworkInterface;}}
35namespace Opie {namespace Net {class OPacketCapturer;}} 37namespace Opie {namespace Net {class OPacketCapturer;}}
36class PacketView; 38class PacketView;
37class WellenreiterConfigWindow; 39class WellenreiterConfigWindow;
38class MLogWindow; 40class MLogWindow;
39class GPS; 41class GPS;
40 42
41class Wellenreiter : public WellenreiterBase { 43class Wellenreiter : public WellenreiterBase {
42 Q_OBJECT 44 Q_OBJECT
43 45
44 public: 46 public:
45 Wellenreiter( QWidget* parent = 0 ); 47 Wellenreiter( QWidget* parent = 0 );
46 ~Wellenreiter(); 48 ~Wellenreiter();
47 49
48 void setConfigWindow( WellenreiterConfigWindow* cw ); 50 void setConfigWindow( WellenreiterConfigWindow* cw );
49 MScanListView* netView() const { return netview; }; 51 MScanListView* netView() const { return netview; };
50 MLogWindow* logWindow() const { return logwindow; }; 52 MLogWindow* logWindow() const { return logwindow; };
51 PacketView* hexWindow() const { return hexwindow; }; 53 PacketView* hexWindow() const { return hexwindow; };
52 bool isDaemonRunning() const { return sniffing; }; 54 bool isDaemonRunning() const { return sniffing; };
53 QString captureFileName() const { return dumpname; }; 55 QString captureFileName() const { return dumpname; };
54 56
55 public: 57 public:
56 bool sniffing; 58 bool sniffing;
59 static Wellenreiter* instance;
60 static void signalHandler( int sig );
57 61
58 protected: 62 protected:
59 virtual void timerEvent( QTimerEvent* ); 63 virtual void timerEvent( QTimerEvent* );
60 64
61 public slots: 65 public slots:
62 void initialTimer(); 66 void initialTimer();
63 67
64 void channelHopped(int); 68 void channelHopped(int);
65 void receivePacket(Opie::Net::OPacket*); 69 void receivePacket(Opie::Net::OPacket*);
66 void startClicked(); 70 void startClicked();
67 void stopClicked(); 71 void stopClicked();
68 72
69 void joinNetwork(const QString&,const QString&,int,const QString&); 73 void joinNetwork(const QString&,const QString&,int,const QString&);
70 74
71 signals: 75 signals:
72 void startedSniffing(); 76 void startedSniffing();
73 void stoppedSniffing(); 77 void stoppedSniffing();
74 78
75 private: 79 private:
76 void handleManagementFrame( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* ); 80 void handleManagementFrame( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* );
77 void handleManagementFrameBeacon( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* ); 81 void handleManagementFrameBeacon( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* );
78 void handleManagementFrameProbeRequest( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* ); 82 void handleManagementFrameProbeRequest( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* );
79 void handleManagementFrameProbeResponse( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* ); 83 void handleManagementFrameProbeResponse( Opie::Net::OPacket* p, Opie::Net::OWaveLanManagementPacket* );
80 void handleControlFrame( Opie::Net::OPacket* p, Opie::Net::OWaveLanControlPacket* control ); 84 void handleControlFrame( Opie::Net::OPacket* p, Opie::Net::OWaveLanControlPacket* control );
81 void handleWlanData( Opie::Net::OPacket* p, Opie::Net::OWaveLanDataPacket* data, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to ); 85 void handleWlanData( Opie::Net::OPacket* p, Opie::Net::OWaveLanDataPacket* data, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to );
82 void handleEthernetData( Opie::Net::OPacket* p, Opie::Net::OEthernetPacket* data, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to ); 86 void handleEthernetData( Opie::Net::OPacket* p, Opie::Net::OEthernetPacket* data, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to );
83 void handleARPData( Opie::Net::OPacket* p, Opie::Net::OARPPacket* arp, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to ); 87 void handleARPData( Opie::Net::OPacket* p, Opie::Net::OARPPacket* arp, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to );
84 void handleIPData( Opie::Net::OPacket* p, Opie::Net::OIPPacket* ip, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to ); 88 void handleIPData( Opie::Net::OPacket* p, Opie::Net::OIPPacket* ip, Opie::Net::OMacAddress& from, Opie::Net::OMacAddress& to );
85 void handleNotification( Opie::Net::OPacket* p ); 89 void handleNotification( Opie::Net::OPacket* p );
86 void doAction( const QString& action, const QString& protocol, Opie::Net::OPacket* p ); 90 void doAction( const QString& action, const QString& protocol, Opie::Net::OPacket* p );
87 QObject* childIfToParse( Opie::Net::OPacket* p, const QString& protocol ); 91 QObject* childIfToParse( Opie::Net::OPacket* p, const QString& protocol );
88 bool checkDumpPacket( Opie::Net::OPacket* p ); 92 bool checkDumpPacket( Opie::Net::OPacket* p );
93 void registerSignalHandler();
89 94
90 private: 95 private:
91 #ifdef QWS 96 #ifdef QWS
92 Opie::Core::OSystem _system; // Opie Operating System identifier 97 Opie::Core::OSystem _system; // Opie Operating System identifier
93 #endif 98 #endif
94 99
95 QString dumpname; 100 QString dumpname;
96 Opie::Net::OWirelessNetworkInterface* iface; 101 Opie::Net::OWirelessNetworkInterface* iface;
97 Opie::Net::OPacketCapturer* pcap; 102 Opie::Net::OPacketCapturer* pcap;
98 WellenreiterConfigWindow* configwindow; 103 WellenreiterConfigWindow* configwindow;
99 GPS* gps; 104 GPS* gps;
100 105
101 //void readConfig(); 106 //void readConfig();
102 //void writeConfig(); 107 //void writeConfig();
103}; 108};
104 109
105 110
106 111
107#endif 112#endif