summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings2/networksettings2/system.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings2/networksettings2/system.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings2/networksettings2/system.cpp318
1 files changed, 318 insertions, 0 deletions
diff --git a/noncore/settings/networksettings2/networksettings2/system.cpp b/noncore/settings/networksettings2/networksettings2/system.cpp
new file mode 100644
index 0000000..99f642e
--- a/dev/null
+++ b/noncore/settings/networksettings2/networksettings2/system.cpp
@@ -0,0 +1,318 @@
1#include <stdlib.h>
2#include <sys/types.h>
3#include <sys/wait.h>
4#include <qfile.h>
5#include <qtextstream.h>
6#include <net/if.h>
7#include <net/if_arp.h>
8#include <netinet/in.h>
9#include <arpa/inet.h>
10#include <sys/ioctl.h>
11#include <sys/socket.h>
12
13#include "resources.h"
14#include "system.h"
15
16#define PROCNETDEV "/proc/net/dev"
17
18static char Dig2Hex[] = {
19 '0', '1', '2', '3',
20 '4', '5', '6', '7',
21 '8', '9', 'A', 'B',
22 'C', 'D', 'E', 'F'
23};
24
25// get HIGH nibble of byte
26#define HN(x) Dig2Hex[(((x)&0xf0)>>4)]
27// get LOW nibble of byte
28#define LN(x) Dig2Hex[((x)&0x0f)]
29
30System::System( void ) : ProbedInterfaces() {
31 probeInterfaces();
32}
33
34System::~System( void ) {
35 if( ProcDevNet )
36 delete ProcDevNet;
37}
38
39int System::execute( const QString & S ) {
40 QString MyS = S;
41 int rv;
42
43 if( S.isEmpty() ) {
44 // loophole to start shell
45 return 8888;
46 }
47 if( getenv("USER") != "root" ) {
48 // use SUDO
49 MyS.prepend( "sudo " );
50 }
51
52 fprintf( stderr, "Executing %s\n", MyS.latin1() );
53
54 rv = system( MyS.latin1() ) ;
55 switch( rv ) {
56 case -1 :
57 // cannot fork
58 return 1;
59 case 127 :
60 // cannot start shell
61 return 2;
62 default :
63 if( WEXITSTATUS(rv) != 0 ) {
64 // error in command
65 return 3;
66 }
67 }
68 // all is fine
69 return 0;
70}
71
72void System::refreshStatistics( InterfaceInfo & I ) {
73 if( ! ProcDevNet ) {
74 return;
75 }
76 // cannot seek on dev
77 ProcDevNet->close();
78 ProcDevNet->open( IO_ReadOnly );
79
80 QString line;
81 QTextStream procTs(ProcDevNet);
82 QStringList SL;
83 int loc = -1;
84 int version;
85
86 procTs.readLine();
87 line = procTs.readLine();
88 // get version
89 if( line.find("compressed") )
90 version = 3;
91 else if( line.find( "bytes" ) )
92 version = 2;
93 else
94 version = 1;
95 while((line = procTs.readLine().simplifyWhiteSpace()) != QString::null) {
96 if( (loc = line.find(":") ) == -1) {
97 continue;
98 }
99
100 if( I.Name != line.left(loc) )
101 continue;
102
103 // tokenize
104 SL = QStringList::split( ' ', line, FALSE );
105
106 // update data
107 switch( version ) {
108 case 1 :
109 I.RcvBytes = SL[1];
110 I.RcvErrors = SL[3];
111 I.RcvDropped = SL[4];
112 I.SndBytes = SL[6];
113 I.SndErrors = SL[8];
114 I.SndDropped = SL[9];
115 I.Collisions = SL[11];
116 break;
117 case 2 :
118 I.RcvBytes = SL[1];
119 I.RcvErrors = SL[3];
120 I.RcvDropped = SL[4];
121 I.SndBytes = SL[7];
122 I.SndErrors = SL[9];
123 I.SndDropped = SL[10];
124 I.Collisions = SL[12];
125 break;
126 case 3 :
127 I.RcvBytes = SL[1];
128 I.RcvErrors = SL[3];
129 I.RcvDropped = SL[4];
130 I.SndBytes = SL[9];
131 I.SndErrors = SL[11];
132 I.SndDropped = SL[12];
133 I.Collisions = SL[14];
134 break;
135 }
136 break;
137 }
138}
139
140//
141// THIS UPDATES THE LIST -> INTERFACES ARE NOT DELETED BUT
142// FLAGGED AS ! 'IsUp' IF NO LONGER PRESENT
143//
144
145void System::probeInterfaces( void ) {
146
147 // probe interfaces
148 int sockfd;
149 // get list of all interfaces
150 struct ifreq ifrs;
151 InterfaceInfo * IFI;
152
153 // flag all as 'down'
154 for( QDictIterator<InterfaceInfo> it( ProbedInterfaces );
155 it.current();
156 ++it ) {
157 it.current()->IsUp = 0;
158 }
159
160 sockfd = socket(PF_INET, SOCK_DGRAM, 0);
161 if(sockfd == -1)
162 return;
163
164 // read interfaces from /proc/dev/net
165 // SIOCGIFCONF does not return ALL interfaces ???!?
166 ProcDevNet = new QFile(PROCNETDEV);
167 if( ! ProcDevNet->open(IO_ReadOnly) ) {
168 delete ProcDevNet;
169 ProcDevNet =0;
170 return;
171 }
172
173 QString line;
174 QString NicName;
175 QTextStream procTs(ProcDevNet);
176 int loc = -1;
177
178 procTs.readLine(); // eat a line
179 procTs.readLine(); // eat a line
180 while((line = procTs.readLine().simplifyWhiteSpace()) != QString::null) {
181 if((loc = line.find(":")) == -1) {
182 continue;
183 }
184
185 NicName = line.left(loc);
186
187 // set name for ioctl
188 strcpy( ifrs.ifr_name, NicName.latin1() );
189
190 if ( ! ( IFI = ProbedInterfaces.find( NicName ) ) ) {
191 // new nic
192 fprintf( stderr, "NEWNIC %s\n", NicName.latin1());
193 IFI = new InterfaceInfo;
194 IFI->Name = line.left(loc);
195 IFI->NetNode = 0;
196 ProbedInterfaces.insert( IFI->Name, IFI );
197
198 // get dynamic info
199 if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) {
200 IFI->IsPointToPoint = ((ifrs.ifr_flags & IFF_POINTOPOINT) == IFF_POINTOPOINT);
201 } else {
202 IFI->IsPointToPoint = 0;
203 }
204
205 // settings that never change
206 IFI->DstAddress = "";
207
208 if( IFI->IsPointToPoint ) {
209 if( ioctl(sockfd, SIOCGIFDSTADDR, &ifrs) >= 0 ) {
210 IFI->DstAddress =
211 inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_dstaddr)->sin_addr);
212 }
213 }
214
215 IFI->CardType = 999999;
216 IFI->MACAddress = "";
217
218 if( ioctl(sockfd, SIOCGIFHWADDR, &ifrs) >= 0 ) {
219 fprintf( stderr, "%s = %d\n", IFI->Name.latin1(),
220 ifrs.ifr_hwaddr.sa_family );
221
222 IFI->CardType = ifrs.ifr_hwaddr.sa_family;
223 switch( ifrs.ifr_hwaddr.sa_family ) {
224 case ARPHRD_ETHER : // regular MAC address
225 // valid address -> convert to regular ::: format
226 // length = 6 bytes = 12 DIGITS -> 6 :
227 IFI->MACAddress.sprintf(
228 "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
229 HN( ifrs.ifr_hwaddr.sa_data[0] ),
230 LN( ifrs.ifr_hwaddr.sa_data[0] ),
231 HN( ifrs.ifr_hwaddr.sa_data[1] ),
232 LN( ifrs.ifr_hwaddr.sa_data[1] ),
233 HN( ifrs.ifr_hwaddr.sa_data[2] ),
234 LN( ifrs.ifr_hwaddr.sa_data[2] ),
235 HN( ifrs.ifr_hwaddr.sa_data[3] ),
236 LN( ifrs.ifr_hwaddr.sa_data[3] ),
237 HN( ifrs.ifr_hwaddr.sa_data[4] ),
238 LN( ifrs.ifr_hwaddr.sa_data[4] ),
239 HN( ifrs.ifr_hwaddr.sa_data[5] ),
240 LN( ifrs.ifr_hwaddr.sa_data[5] )
241 );
242 break;
243#ifdef ARPHRD_IEEE1394
244 case ARPHRD_IEEE1394 : // Firewire Eth address
245 IFI->MACAddress.sprintf(
246 "%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-00-00",
247 HN( ifrs.ifr_hwaddr.sa_data[0] ),
248 LN( ifrs.ifr_hwaddr.sa_data[0] ),
249 HN( ifrs.ifr_hwaddr.sa_data[1] ),
250 LN( ifrs.ifr_hwaddr.sa_data[1] ),
251 HN( ifrs.ifr_hwaddr.sa_data[2] ),
252 LN( ifrs.ifr_hwaddr.sa_data[2] ),
253 HN( ifrs.ifr_hwaddr.sa_data[3] ),
254 LN( ifrs.ifr_hwaddr.sa_data[3] ),
255 HN( ifrs.ifr_hwaddr.sa_data[4] ),
256 LN( ifrs.ifr_hwaddr.sa_data[4] ),
257 HN( ifrs.ifr_hwaddr.sa_data[5] ),
258 LN( ifrs.ifr_hwaddr.sa_data[5] ),
259 HN( ifrs.ifr_hwaddr.sa_data[6] ),
260 LN( ifrs.ifr_hwaddr.sa_data[6] ),
261 HN( ifrs.ifr_hwaddr.sa_data[7] ),
262 LN( ifrs.ifr_hwaddr.sa_data[7] ),
263 HN( ifrs.ifr_hwaddr.sa_data[8] ),
264 LN( ifrs.ifr_hwaddr.sa_data[8] ),
265 HN( ifrs.ifr_hwaddr.sa_data[9] ),
266 LN( ifrs.ifr_hwaddr.sa_data[9] ),
267 HN( ifrs.ifr_hwaddr.sa_data[10] ),
268 LN( ifrs.ifr_hwaddr.sa_data[10] ),
269 HN( ifrs.ifr_hwaddr.sa_data[11] ),
270 LN( ifrs.ifr_hwaddr.sa_data[11] ),
271 HN( ifrs.ifr_hwaddr.sa_data[12] ),
272 LN( ifrs.ifr_hwaddr.sa_data[12] ),
273 HN( ifrs.ifr_hwaddr.sa_data[13] ),
274 LN( ifrs.ifr_hwaddr.sa_data[13] )
275 );
276 break;
277#endif
278 case ARPHRD_PPP : // PPP
279 break;
280 case ARPHRD_IEEE80211 : // WLAN
281 break;
282 case ARPHRD_IRDA : // IRDA
283 break;
284 }
285 }
286 } else // else already probed before -> just update
287 fprintf( stderr, "OLDNIC %s\n", NicName.latin1());
288
289 // get dynamic info
290 if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) {
291 IFI->IsUp = ((ifrs.ifr_flags & IFF_UP) == IFF_UP);
292 IFI->HasMulticast = ((ifrs.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST);
293 } else {
294 IFI->IsUp = 0;
295 IFI->HasMulticast = 0;
296 }
297
298 if( ioctl(sockfd, SIOCGIFADDR, &ifrs) >= 0 ) {
299 IFI->Address =
300 inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_addr)->sin_addr);
301 } else {
302 IFI->Address = "";
303 IFI->IsUp = 0;
304 }
305 if( ioctl(sockfd, SIOCGIFBRDADDR, &ifrs) >= 0 ) {
306 IFI->BCastAddress =
307 inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_broadaddr)->sin_addr);
308 } else {
309 IFI->BCastAddress = "";
310 }
311 if( ioctl(sockfd, SIOCGIFNETMASK, &ifrs) >= 0 ) {
312 IFI->Netmask =
313 inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_netmask)->sin_addr);
314 } else {
315 IFI->Netmask = "";
316 }
317 }
318}