Diffstat (limited to 'noncore/settings/networksettings2/networksettings2/system.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings2/networksettings2/system.cpp | 318 |
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 | |||
18 | static 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 | |||
30 | System::System( void ) : ProbedInterfaces() { | ||
31 | probeInterfaces(); | ||
32 | } | ||
33 | |||
34 | System::~System( void ) { | ||
35 | if( ProcDevNet ) | ||
36 | delete ProcDevNet; | ||
37 | } | ||
38 | |||
39 | int 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 | |||
72 | void 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 | |||
145 | void 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 | } | ||