• # checkpeer

    Posté par . En réponse au message pppd/ADSL: probleme de reconnexion apres une déconnexion. Évalué à 3.

    j'ai un script qui permet de compter les paquets sur une interface ... et si aucun ne bouge ... fait un ping sur le peer et revérifie etc.


    ca marche depuis 3 ans chez moi non stop avec mon speedtouch usb ....

    #!/usr/bin/perl
    #use strict;
    use Net::Ping;

    my $line;my $dummy;my $peer;my $ip1;my $ip2;my $ip3;my $ip4;my $p;my $field;
    my $status="OK";
    my $sleep=60;
    my $peermissing=0;
    my $peerunreach=0;
    my $oldrecvpack=0;
    my $recvpackets=0;

    # sub performing restart of pppd and relevant process
    ##
    sub restartppp {
    system("killall pppd;sleep 2;/etc/init.d/ADSL start");
    }

    # sub performing restart of usb and relevant process
    ##
    sub restartusb {
    }

    # sub to update number of packets received on ppp0
    ##
    sub updatepackets {
    my $inpackets=0;
    my $line;
    my $dummy;
    $line=`ifconfig ppp0 | grep "RX packets:"`;
    chomp $line;
    ($dummy,$inpackets)=split(":",$line);
    $line=$inpackets;
    ($inpackets,$dummy)=split(" ",$line);
    return $inpackets;
    }

    # Start of script
    ##

    #Update number of packets the first time
    $recvpackets=updatepackets();
    $oldrecvpack=$recvpackets;
    open(LOG,">>/var/log/checkpeer.log");
    print "Starting to monitor ppp0 link\n";
    while ($status ne "quit"){
    #Testing if the ppp interface is OK by fetching the peer IP address
    $line=`ifconfig ppp0 | grep inet `;
    chomp $line;
    ($dummy,$dummy,$field)=split (":",$line);
    ($peer,$dummy)=split (" ",$field);
    ($ip1,$ip2,$ip3,$ip4)=split ("\\.",$peer);
    if ($ip1<=0 || $ip1>255 || $ip2<=0 || $ip2>255 || $ip3<=0 || $ip3>255 || $ip4<=0 || $ip4>255){
    $status="peer missing";
    }
    else{
    #Test if we have received new packets on ppp0 to save pinging peer
    $recvpackets=updatepackets();
    if ($recvpackets > $oldrecvpack){
    $oldrecvpack=$recvpackets;
    $status="packets detected";
    }
    elsif ($recvpackets < $oldrecvpack){
    $oldrecvpack=$recvpackets;
    $status="interface reset";
    }
    else {# No packets received lately.Checking peer by pinging it ...
    $p = Net::Ping->new("icmp");
    if ($p->ping($peer,1)){
    $status="peer reacheable";
    }
    else{
    $status="peer unreacheable";
    }
    $p->close();
    #Update packets count so next comparison takes the ping into account
    $recvpackets=updatepackets();
    $oldrecvpack=$recvpackets;
    }
    }

    #From here, we take different actions depending on the previous results
    if ($status eq "peer missing"){
    $peermissing++;
    print scalar(localtime()).": PPPD is being started (peer missing)\n";
    restartppp();
    #Increase sleep time each time in case pppd needs more time
    $sleep=30+$peermissing*5;
    if ($peermissing >= 5){
    print scalar(localtime()).": USB is being restarted\n";
    restartusb();
    $peerunreach=0;
    $sleep=120;
    }
    }
    elsif ($status eq "peer unreacheable"){
    $peerunreach++;
    $sleep=5;
    print scalar(localtime()).": PEER $peer is down ($peerunreach time(s))"."\n";
    if ($peerunreach >= 5){
    print scalar(localtime()).": PPPD is being restarted (peer unreacheable)\n";
    restartppp();
    $peerunreach=0;
    #Increase sleep time each time in case pppd needs more time
    $sleep=15+$peerunreach;
    }
    }
    elsif ($status eq "packets detected"){
    $sleep=30;
    # print scalar(localtime()).": PPP0 traffic increased to $recvpackets packets. Skipping ping"."\n";
    $peerunreach=0;
    }
    elsif ($status eq "interface reset"){
    $sleep=20;
    $peerunreach=0;
    print scalar(localtime()).": PPP0 interface reset $recvpackets packets. Skipping ping"."\n";
    }
    elsif ($status eq "peer reacheable"){
    # print scalar(localtime()).": PEER $peer is alive"."\n";
    $sleep=60;
    $peermissing=0;
    $peerunreach=0;
    }
    # print scalar(localtime()).": SLEEP for $sleep seconds\n";
    sleep $sleep;
    }