http://www.perlmonks.org?node_id=24555


in reply to Re: Checking ADSL connection
in thread Checking ADSL connection

Please do post your code. I never completed my intended final version; instead I used Downtime and pasted in my X10 code. However, I'd be interested in seeing what you did differently.

The logic I used for my script is similar to yours, like so:

Ping the modem every 30 seconds # Not possible with mine, or I would Ping the "internet" every 5 minutes if ping fails Increment failure counter If counter >= 3 Notify via internal email / telephone page of serious problem +and exit power-cycle modem wait 45 seconds ping internet if up, notify of problem/resolution if internet still not up, repeat

- email Ozymandias

Replies are listed 'Best First'.
RE: (Ozymandias: Post it!) RE:(2) Checking ADSL connection
by lhoward (Vicar) on Jul 26, 2000 at 23:36 UTC
    Here is my code... It is VERY tuned to my particular situation and doesn't have many (any?) comments...

    Ozymandias, I haven't looked at your code recently, but one of the things emphasized in mine is a strong logging capability (via syslog).

    One thing I'd like to add is "upstream failure detection" where it will not restart the connection if the modem and the next router "upstream to the internet" both respond to pings. Also I'd like to add code to do error-checking of the results of the "/etc/rc.d/init.d/pppoe start" command.

    #!/usr/bin/perl -w use strict; use Device::SerialPort; use ControlX10::CM11; use Net::Ping; use Net::Syslog; use POSIX; # DAEMON stuff my $pid=fork; exit if $pid; die "Couldn't fork: $!" unless defined $pid; POSIX::setsid() or die "Can't start a new session: $!"; # end DAEMON stuff my $s=new Net::Syslog(Facility=>'local5', Priority=>'notice', Name=>'dslmonitor'); $SIG{TERM}=sub { $s->send('DSL monitoring stopping'); exit; }; $s->send('DSL monitoring started'); my $i; my $m; my $ctr=0; my $tdown; while(1){ $m=is_modem_up(); if(!$m){ $s->send("modem not responding to ping"); } $i=is_internet_up() if(($ctr==0)||(!$m)); if((!$i)||(!$m)){ $s->send('lost internet connection'); $tdown=time(); } while((!$i)||(!$m)){ $s->send('stopping pppoe'); stop_pppoe(); $m=0; while(!$m){ $s->send('power cycling DSL modem'); power_cycle_modem(); $s->send('power cycling complete, waiting for modem to respond t +o ping'); my $b=time; my $tdiff=time()-$b; while(($tdiff<30)&&(!$m)){ sleep 1; $m=is_modem_up(); $tdiff=time()-$b; } if($m){ $s->send("modem up $tdiff sec after cycle\n"); }else{ $s->send("modem not responding to pings $tdiff seconds after r +eboot, power cycle modem again"); } } $s->send("waiting 30 seconds for modem DSL negotiation to occur"); sleep 30; $s->send("starting pppoe"); start_pppoe(); $s->send("pppoe start complete, waiting 5 seconds"); sleep 5; $s->send("probing for connectivity"); $i=is_internet_up(); $m=is_modem_up(); if(!$m){ $s->send("modem not responding to ping"); } if(($i)&&($m)){ $tdown=time()-$tdown; my $se=$tdown%60; my $m=(int($tdown/(60)))%60; my $h=(int($tdown/(60*60)))%24; my $d=(int($tdown/(60*60*24))); $s->send("internet connection restored after $d days, $h hours, +$m minutes and $se seconds of downtime"); }else{ $s->send("pppoe negotiation failed"); } } sleep 30; $ctr=($ctr+1)%10; } sub is_modem_up{ my $p=new Net::Ping("icmp"); for(my $c=0;$c<3;$c++){ my $i=$p->ping('10.0.0.1',2);; return $i if($i); } return 0; } sub is_internet_up{ my $p=new Net::Ping("icmp"); my @inethosts=('192.5.5.241','202.12.27.33','128.63.2.53'); for(my $c=0;$c<3;$c++){ foreach(@inethosts){ my $i= $p->ping($_,5); return $i if($i); } } $s->send("internet not responding to ping"); return 0; } sub stop_pppoe{ system '/etc/rc.d/init.d/adsl stop >/dev/null 2>/dev/null'; } sub start_pppoe{ system '/etc/rc.d/init.d/adsl start >/dev/null 2>/dev/null'; # checking output would be a good idea } sub power_cycle_modem{ #my $serial_port = new Device::SerialPort('/dev/x10'); my $serial_port = new Device::SerialPort('/dev/ttyS0'); if(!defined $serial_port){ die "error openign serial \"$!\""; } $serial_port->baudrate(4800); $serial_port->databits(8); $serial_port->parity('none'); $serial_port->stopbits(1); $serial_port->handshake('none'); $serial_port->stty_echo(0); $serial_port->read_const_time(5000); $serial_port->read_char_time(5); &ControlX10::CM11::send($serial_port, 'B1'); &ControlX10::CM11::send($serial_port, 'BK'); sleep 5; &ControlX10::CM11::send($serial_port, 'B1'); &ControlX10::CM11::send($serial_port, 'BJ'); }