1 // copyright: (C) 2000 by SuSE GmbH
2 // author: arvin@suse.de
3 // WvStreamsified by Patrick Patterson (ppatters@nit.ca)
13 #include <net/route.h>
14 #include <sys/socket.h>
15 #include <sys/types.h>
19 #include "wvdialmon.h"
23 WvDialMon::WvDialMon()
24 : log( "WvDial", WvLog::Debug
),
25 err( log
.split( WvLog::Error
) ),
28 // executename = WvString( "" );
29 connectmsg
= WvString( "Connected... Press Ctrl-C to disconnect\n" );
31 // usleep_time = 1000;
35 route_fd
= (FILE *) 0;
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
);
48 WvDialMon::~WvDialMon()
50 regfree( &rx_status
);
52 regfree( &rx_namesrv
);
56 void WvDialMon::setdnstests (WvString dnstest1
, WvString dnstest2
)
58 WvDialMon::dnstest1
= dnstest1
;
59 WvDialMon::dnstest2
= dnstest2
;
63 void WvDialMon::reset()
68 const int WvDialMon::auth_failed()
74 int WvDialMon::get_quotedtext(char *dest
, const char *line
)
78 if( regexec( &rx_quote
, line
, 1, &rm
[0], 0 ) == REG_NOMATCH
)
80 err("***** no quoted text found in `%s' *****\n", line
);
84 int s
= rm
[0].rm_so
, e
= rm
[0].rm_eo
;
85 strncpy (dest
, &line
[s
], e
-s
);
91 char *WvDialMon::analyse_line(const char *line
)
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
);
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
);
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) )
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");
166 log( "Default route Ok.\n" );
168 log( "Default route failure.\n" );
174 log( "Nameserver (DNS) Ok.\n" );
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 ) {
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));
196 // int devnullw = open("/dev/null",O_WRONLY,0);
197 // dup2(devnullw, fileno(stdout));
198 // dup2(devnullw, fileno(stderr));
203 // for( int tty = 3; tty < 256; 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) );
223 // if( pid < (pid_t) 0 ) // the fork failed
224 // fprintf( stderr, "error: can't fork child process\n" );
226 // output( "Started `", executename, "' successfully\n" );
233 log("Script /etc/ppp/ip-up failed (return value: %s )\n", p
);
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");
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)
269 if (strncmp(line
, "Using interface", 15) == 0)
274 if( strncmp(line
,"Terminating", 11 ) == 0 )
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)
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";
322 route_fd
= fopen (path
, "r");
323 if (route_fd
== NULL
) {
324 log( "can't read %s\n", path
);
328 route_dev_col
= 0; /* default to usual columns */
335 /* parse header line */
336 if (fgets(route_buffer
, sizeof(route_buffer
), route_fd
) != 0)
338 char *p
= route_buffer
, *q
;
340 for (col
= 0; col
< ROUTE_MAX_COLS
; ++col
)
343 if ((q
= strtok(p
, route_delims
)) == 0)
345 if (strcasecmp(q
, "iface") == 0)
347 else if (strcasecmp(q
, "destination") == 0)
348 route_dest_col
= col
;
349 else if (strcasecmp(q
, "gateway") == 0)
351 else if (strcasecmp(q
, "flags") == 0)
352 route_flags_col
= col
;
353 else if (strcasecmp(q
, "mask") == 0)
354 route_mask_col
= col
;
357 if (used
&& col
>= route_num_cols
)
358 route_num_cols
= col
+ 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
;
376 memset (rt
, '\0', sizeof (struct rtentry
));
378 if (fgets (route_buffer
, sizeof (route_buffer
), route_fd
) == (char *) 0)
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 */
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
];
402 /********************************************************************
404 * defaultroute_exists - determine if there is a default route
407 int WvDialMon::defaultroute_exists (struct rtentry
*rt
)
411 if (!open_route_table())
414 while (read_route_table(rt
) != 0)
416 if ((rt
->rt_flags
& RTF_UP
) == 0)
419 if (kernel_version
> KVERSION(2,1,0) && SIN_ADDR(rt
->rt_genmask
) != 0)
421 if (SIN_ADDR(rt
->rt_dst
) == 0L)
432 int WvDialMon::check_dfr()
434 struct rtentry def_rt
;
436 if( !defaultroute_exists( &def_rt
) )
439 // FIXME: check if the gateway is set correct
444 int WvDialMon::check_dns_name( const char *name
)
447 hp
= gethostbyname( name
);
450 log( "warning, can't find address for `%s`\n", name
);
454 // err("***** official name for `%s' is `%s' *****\n", name, hp->h_name );
459 int WvDialMon::check_dns()
461 char name
[] = "/etc/resolv.conf";
463 FILE *fin
= fopen( name
, "r" );
465 log( "warning, can't read `%s`\n", name
);
469 const int size
= 100;
473 int found_namesrv
= 0;
475 while( fgets( line
, size
, fin
) != NULL
)
477 if( line
[0] == '\n' || line
[0] == '#' )
480 if( line
[ strlen(line
)-1 ] == '\n' )
481 line
[ strlen(line
)-1 ] = '\0';
483 if( regexec( &rx_namesrv
, line
, 1, &rm
[0], 0 ) == 0 )
495 log( "warning, no nameserver found `%s`\n",name
);
499 if (!check_dns_name ((const char* ) dnstest1
) || !check_dns_name ((const char* ) dnstest2
))
501 log( "warning, address lookup does not work\n" );