Enable debugging for openssl port.
[wvapps.git] / wvdial / wvdialmon.cc
blob8d718a5380b83923d70d0f5345b76ea27bbd9bdc
1 // copyright: (C) 2000 by SuSE GmbH
2 // author: arvin@suse.de
3 // WvStreamsified by Patrick Patterson (ppatters@nit.ca)
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <regex.h>
12 #include <netdb.h>
13 #include <net/route.h>
14 #include <sys/socket.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
19 #include "wvdialmon.h"
23 WvDialMon::WvDialMon()
24 : log( "WvDial", WvLog::Debug ),
25 err( log.split( WvLog::Error ) ),
26 buffer("")
28 // executename = WvString( "" );
29 connectmsg = WvString( "Connected... Press Ctrl-C to disconnect\n" );
31 // usleep_time = 1000;
32 do_check_dfr = 0;
33 do_check_dns = 0;
35 route_fd = (FILE *) 0;
37 buffer.setsize(100);
39 regcomp( &rx_status, "status *= *", REG_EXTENDED );
40 regcomp( &rx_quote, "\\\"[^\\\"]+\\\"", REG_EXTENDED );
41 regcomp( &rx_namesrv, "nameserver *[0-9]+.[0-9]+.[0-9]+.[0-9]+", REG_EXTENDED );
43 reset();
48 WvDialMon::~WvDialMon()
50 regfree( &rx_status );
51 regfree( &rx_quote );
52 regfree( &rx_namesrv );
56 void WvDialMon::setdnstests (WvString dnstest1, WvString dnstest2)
58 WvDialMon::dnstest1 = dnstest1;
59 WvDialMon::dnstest2 = dnstest2;
63 void WvDialMon::reset()
65 _auth_failed = 0;
68 const int WvDialMon::auth_failed()
70 return _auth_failed;
74 int WvDialMon::get_quotedtext(char *dest, const char *line)
76 regmatch_t rm[1];
78 if( regexec( &rx_quote, line, 1, &rm[0], 0 ) == REG_NOMATCH )
80 err("***** no quoted text found in `%s' *****\n", line );
81 return 0;
84 int s = rm[0].rm_so, e = rm[0].rm_eo;
85 strncpy (dest, &line[s], e-s);
86 dest[e-s] = '\0';
88 return 1;
91 char *WvDialMon::analyse_line(const char *line)
93 regmatch_t rm[1];
95 if (line == NULL )
96 return NULL;
98 // PAP stuff
99 //
100 if (strstr(line, "AuthReq") != NULL)
101 log("Authentication (PAP) started\n");
103 if (strstr(line, "AuthAck") != NULL)
104 log("Authentication (PAP) successful\n");
106 if (strstr(line, "AuthNak") != NULL) {
107 log("Authentication (PAP) failed");
109 char buf[strlen(line)];
110 if( get_quotedtext( buf, line ) )
111 log(" (Message: %s )\n", buf);
113 _auth_failed = 1;
117 // CHAP stuff
119 if (strstr(line, "CHAP Challenge") != NULL)
120 log("Authentication (CHAP) started\n");
122 if (strstr(line, "CHAP Success") != NULL)
123 log("Authentication (CHAP) successful\n");
125 if (strstr(line, "CHAP Failure") != NULL) {
126 log("Authentication (CHAP) failed");
128 char buf[strlen(line)];
129 if( get_quotedtext( buf, line ) )
130 log(" (Message: %s )\n", buf);
132 _auth_failed = 1;
136 // IP stuff
138 if (!strncmp(line, "local IP address", 17) ||
139 !strncmp(line, "remote IP address", 17) ||
140 !strncmp(line, "primary DNS address", 20) ||
141 !strncmp(line, "secondary DNS address", 20) )
143 log("%s\n",line);
146 // Script stuff
148 if (strncmp(line, "Script", 6) == 0)
150 if (strstr(line, "/etc/ppp/ip-up") != NULL && strstr(line, "finished") != NULL)
152 if( regexec( &rx_status, line, 1, &rm[0], 0 ) == 0 )
154 const char *p = &line[ rm[0].rm_eo ];
156 // err("***** status is `%s' *****\n", p2 );
158 if (strcmp( p, "0x0") == 0)
161 log("Script /etc/ppp/ip-up run successful\n");
163 if( do_check_dfr )
165 if( check_dfr() )
166 log( "Default route Ok.\n" );
167 else
168 log( "Default route failure.\n" );
171 if( do_check_dns )
173 if( check_dns() )
174 log( "Nameserver (DNS) Ok.\n" );
175 else
176 log( "Nameserver (DNS) failure, the connection may not work.\n" );
179 log( "%s\n", connectmsg );
181 // execute whatever the user wants to
183 // if( executename.len() > 0 ) {
185 // fflush(stdout);
186 // fflush(stderr);
188 // pid_t pid = fork();
190 // if( pid == (pid_t) 0 ) { // we are the child
192 // int devnullr = open("/dev/null",O_RDONLY,0);
193 // dup2(devnullr, fileno(stdin));
194 // close(devnullr);
196 // int devnullw = open("/dev/null",O_WRONLY,0);
197 // dup2(devnullw, fileno(stdout));
198 // dup2(devnullw, fileno(stderr));
199 // close(devnullw);
200 // fflush(stdout);
201 // fflush(stderr);
203 // for( int tty = 3; tty < 256; tty++ )
204 // close(tty);
206 // usleep( usleep_time );
208 // // executename = Netscape -remote "reload()", macht probleme
209 // // wenn mehrere netscapes auf dem xserver laufen (dann
210 // // empfängt zufällig einer die message)
212 // const char *new_argv[4];
213 // new_argv[0] = "sh";
214 // new_argv[1] = "-c";
215 // new_argv[2] = executename;
216 // new_argv[3] = NULL;
218 // execv( "/bin/sh", (char *const *) new_argv );
220 // fprintf( stderr, "exec failed: %s\n", strerror(errno) );
221 // }
223 // if( pid < (pid_t) 0 ) // the fork failed
224 // fprintf( stderr, "error: can't fork child process\n" );
225 // else
226 // output( "Started `", executename, "' successfully\n" );
228 // }
231 else
233 log("Script /etc/ppp/ip-up failed (return value: %s )\n", p);
237 else
239 // fprintf( stderr, "***** no status found *****\n" );
244 if (strstr(line, "/etc/ppp/ip-down") != NULL && strstr(line, "started") != NULL)
245 log("Script /etc/ppp/ip-down started\n");
249 // TermReq stuff
251 if (strstr(line, "LCP TermReq") != NULL)
253 log("Terminate Request");
255 char buf[strlen(line)];
256 if( get_quotedtext( buf, line ) )
257 log(" (Message: %s )\n", buf);
261 // connect time stuff
263 if (strncmp(line, "Connect time", 12) == 0)
264 log("%s\n",line);
267 // interface stuff
269 if (strncmp(line, "Using interface", 15) == 0)
270 log("%s\n", line);
272 // terminate stuff
274 if( strncmp(line,"Terminating", 11 ) == 0 )
275 log("%s\n",line);
278 return buffer.edit();
283 /********* taken from pppd ************/
285 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
287 #define SET_SA_FAMILY(addr, family) \
288 memset ((char *) &(addr), '\0', sizeof(addr)); \
289 addr.sa_family = (family);
291 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
293 #define ROUTE_MAX_COLS 12
295 /********************************************************************
297 * close_route_table - close the interface to the route table
300 void WvDialMon::close_route_table ()
302 if (route_fd != (FILE *) 0)
304 fclose (route_fd);
305 route_fd = (FILE *) 0;
309 /********************************************************************
311 * open_route_table - open the interface to the route table
314 static char route_delims[] = " \t\n";
316 int WvDialMon::open_route_table ()
318 char path[] = "/proc/net/route";
320 close_route_table();
322 route_fd = fopen (path, "r");
323 if (route_fd == NULL) {
324 log( "can't read %s\n", path );
325 return 0;
328 route_dev_col = 0; /* default to usual columns */
329 route_dest_col = 1;
330 route_gw_col = 2;
331 route_flags_col = 3;
332 route_mask_col = 7;
333 route_num_cols = 8;
335 /* parse header line */
336 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0)
338 char *p = route_buffer, *q;
339 int col;
340 for (col = 0; col < ROUTE_MAX_COLS; ++col)
342 int used = 1;
343 if ((q = strtok(p, route_delims)) == 0)
344 break;
345 if (strcasecmp(q, "iface") == 0)
346 route_dev_col = col;
347 else if (strcasecmp(q, "destination") == 0)
348 route_dest_col = col;
349 else if (strcasecmp(q, "gateway") == 0)
350 route_gw_col = col;
351 else if (strcasecmp(q, "flags") == 0)
352 route_flags_col = col;
353 else if (strcasecmp(q, "mask") == 0)
354 route_mask_col = col;
355 else
356 used = 0;
357 if (used && col >= route_num_cols)
358 route_num_cols = col + 1;
359 p = NULL;
363 return 1;
366 /********************************************************************
368 * read_route_table - read the next entry from the route table
371 int WvDialMon::read_route_table(struct rtentry *rt)
373 char *cols[ROUTE_MAX_COLS], *p;
374 int col;
376 memset (rt, '\0', sizeof (struct rtentry));
378 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
379 return 0;
381 p = route_buffer;
382 for (col = 0; col < route_num_cols; ++col) {
383 cols[col] = strtok(p, route_delims);
384 if (cols[col] == NULL)
385 return 0; /* didn't get enough columns */
386 p = NULL;
389 SET_SA_FAMILY (rt->rt_dst, AF_INET);
390 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
392 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
393 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
394 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
396 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
397 rt->rt_dev = cols[route_dev_col];
399 return 1;
402 /********************************************************************
404 * defaultroute_exists - determine if there is a default route
407 int WvDialMon::defaultroute_exists (struct rtentry *rt)
409 int result = 0;
411 if (!open_route_table())
412 return 0;
414 while (read_route_table(rt) != 0)
416 if ((rt->rt_flags & RTF_UP) == 0)
417 continue;
419 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
420 continue;
421 if (SIN_ADDR(rt->rt_dst) == 0L)
423 result = 1;
424 break;
428 close_route_table();
429 return result;
432 int WvDialMon::check_dfr()
434 struct rtentry def_rt;
436 if( !defaultroute_exists( &def_rt ) )
437 return 0;
439 // FIXME: check if the gateway is set correct
441 return 1;
444 int WvDialMon::check_dns_name( const char *name )
446 struct hostent *hp;
447 hp = gethostbyname( name );
448 if( hp == NULL )
450 log( "warning, can't find address for `%s`\n", name );
451 return 0;
454 // err("***** official name for `%s' is `%s' *****\n", name, hp->h_name );
456 return 1;
459 int WvDialMon::check_dns()
461 char name[] = "/etc/resolv.conf";
463 FILE *fin = fopen( name, "r" );
464 if( fin == NULL ) {
465 log( "warning, can't read `%s`\n", name );
466 return 0;
469 const int size = 100;
470 char line[size];
472 regmatch_t rm[1];
473 int found_namesrv = 0;
475 while( fgets( line, size, fin ) != NULL )
477 if( line[0] == '\n' || line[0] == '#' )
478 continue;
480 if( line[ strlen(line)-1 ] == '\n' )
481 line[ strlen(line)-1 ] = '\0';
483 if( regexec( &rx_namesrv, line, 1, &rm[0], 0 ) == 0 )
485 found_namesrv = 1;
486 break;
491 fclose( fin );
493 if( !found_namesrv )
495 log( "warning, no nameserver found `%s`\n",name);
496 return 0;
499 if (!check_dns_name ((const char* ) dnstest1) || !check_dns_name ((const char* ) dnstest2))
501 log( "warning, address lookup does not work\n" );
502 return 0;
505 return 1;