Redémarrer automatiquement sa LiveBox V2

Depuis quelque temps, j’ai remarqué que ma connexion internet pouvait avoir tendance à ramer un peu (et parfois beaucoup). En cherchant un peu je me suis rendu compte que depuis la mise à jour du Firmware de ma Livebox (V2), elle avait pris la fâcheuse habitude de se resynchroniser sur l’ADSL assez régulièrement et à chaque fois, je perdais un peu plus de vitesse.

J’ai eu beau chercher sur internet mais je ne trouvais rien qui me permettait de résoudre ce problème et aucun script ne fonctionnait (en tout cas ceux que j’avais pu trouver).

J’ai donc du me résoudre à explorer moi même cette possibilité.

Après quelques essais, je me suis rendu compte qu’en exploitant le mode développeur de Chrome, il était possible de récupérer les requêtes Java entre le client (votre navigateur) et le serveur Web de la Box ; j’ai ensuite put comprendre quels cookies générer et quelles requêtes envoyer pour que cela marche.

Au final, j’ai codé le script suivant sous Python (donc théoriquement exploitable sous Windows en installant tout ce qui va bien) :

#!/usr/bin/python
import pycurl
import urllib
import json
from io import BytesIO

import re
try:
    from io import BytesIO
except ImportError:
    from StringIO import StringIO as BytesIO



headers = {}
def header_function(header_line):
    # HTTP standard specifies that headers are encoded in iso-8859-1.
    # On Python 2, decoding step can be skipped.
    # On Python 3, decoding step is required.
    header_line = header_line.decode('iso-8859-1')

    # Header lines include the first status line (HTTP/1.x ...).
    # We are going to ignore all lines that don't have a colon in them.
    # This will botch headers that are split on multiple lines...
    if ':' not in header_line:
        return

    # Break the header line into header name and value.
    name, value = header_line.split(':', 1)

    # Remove whitespace that may be present.
    # Header lines include the trailing newline, and there may be whitespace
    # around the colon.
    name = name.strip()
    value = value.strip()

    # Header names are case insensitive.
    # Lowercase name here.
    name = name.lower()

    # Now we can actually record the header name and value.
    headers[name] = value

box_ip='Livebox IP Here'

#adjust these parameters for your own
#min_time : Default 900 seconds, min 15mins working before reboot box
#min_down_speed : don't reboot if above
#min_up_speed : don't rebove if above

lbox_data = {'username':'Box Admin Username Here',
                'password':'Box Admin Password Here',
                'box_ip':box_ip,
                'min_time':900,
                'min_down_speed':5000,
                'min_up_speed':750}

post_data = {'login':'username='+lbox_data['username']+'&password='+lbox_data['password'],
                'dsl_status':'{"parameters":{"mibs":"dsl","flag":"","traverse":"down"}}',
                'reboot':'{"parameters":{}}',
                'led_status':''}

#define url
urls={'login':'http://'+box_ip+'/authenticate?'+post_data['login'],
'dsl_status':'http://'+box_ip+'/sysbus/NeMo/Intf/data:getMIBs',
'reboot':'http://'+box_ip+'/sysbus/NMC:reboot',
'led_status':'http://'+box_ip+'/sysbus/LED'}

buffer=BytesIO()
#Get Login sessid and contextID
c=pycurl.Curl()
c.setopt(c.URL, urls['login'])
c.setopt(c.POST, 1)
c.setopt(c.POSTFIELDS, post_data['login'])
c.setopt(c.VERBOSE, 0)
c.setopt(c.WRITEFUNCTION, buffer.write)
# Set our header function.
c.setopt(c.HEADERFUNCTION, header_function)
c.perform()
login_response=json.loads(buffer.getvalue())

buffer=BytesIO()
lb_id=headers['set-cookie'].split('/',1)[0]
sessid=(headers['set-cookie'].split('=',1)[1]).rsplit(';',1)[0]

context_id=login_response['data']['contextID']

#Define Cookies
new_cookie = str(lb_id+'/zoom-accessibility=small; \
'+lb_id+'/contrast-accessibility=contrast1; \
'+lb_id+'/language=fr; \
'+lb_id+'/possibleLanguages=en,fr; \
'+lb_id+'/sessid='+sessid+'; \
'+lb_id+'/context='+context_id+'; \
'+lb_id+'/login=admin; \
'+lb_id+'/WanInterfaceConfig=DSL')

#get Dsl Status
c.setopt(c.URL, urls['dsl_status'])
c.setopt(c.POST, 1)
c.setopt(c.POSTFIELDS, post_data['dsl_status'])
c.setopt(c.VERBOSE, 0)
c.setopt(c.HTTPHEADER, [str('X-Context:'+context_id)])
c.setopt(c.COOKIE,new_cookie)
c.setopt(c.WRITEFUNCTION, buffer.write)
c.perform()
dsl_status_response=json.loads(buffer.getvalue())

last_change=dsl_status_response['status']['dsl']['dsl0']['LastChange']
down_speed=dsl_status_response['status']['dsl']['dsl0']['DownstreamCurrRate']
up_speed=dsl_status_response['status']['dsl']['dsl0']['UpstreamCurrRate']

#get Led Status, used to know if Box is incall or not (don't reset in this case)
buffer=BytesIO()
c.setopt(c.URL, urls['led_status'])
c.setopt(c.POST, 0)
c.setopt(c.VERBOSE, 0)
c.setopt(c.HTTPHEADER, [str('X-Context:'+context_id)])
c.setopt(c.COOKIE,new_cookie)
c.setopt(c.WRITEFUNCTION, buffer.write)
c.perform()
led_status=json.loads(buffer.getvalue())

for led in led_status['instances']:
        if led['objectInfo']['key'] == "VoIP Led" :
                for voip_led_param in led['parameters']:
                        if voip_led_param['name'] == "State" :
                                if voip_led_param['value'] == "Off" or voip_led_param['value'] == "Solid" :
                                        IsCalling=0
                                elif voip_led_param['value'] == "FlashSlow" or voip_led_param['value'] == "FlashFast" :
                                        IsCalling=1
                                else:
                                        IsCalling=0

if ( last_change >= lbox_data['min_time'] ) and not IsCalling:
        if ( down_speed < lbox_data['min_down_speed'] or up_speed < lbox_data['min_up_speed'] ):
                c.setopt(c.URL, urls['reboot'])
                c.setopt(c.POSTFIELDS, post_data['reboot'])
                c.setopt(c.VERBOSE, 0)
                c.setopt(c.HTTPHEADER, [str('X-Context:'+context_id)])
                c.setopt(c.COOKIE,new_cookie)
                c.setopt(c.WRITEFUNCTION, buffer.write)
                c.perform()
c.close()

Pour expliquer rapidement le fonctionnement :

– On se connecte à la Box via Curl et on récupère diverses infos pour créer les cookies qui vont bien

– On récupère ensuite l’état de la connexion ADSL et des voyants de la Box

– On vérifie que l’on ne soit pas en communication (ça serait ballot de couper le siffler à votre interlocuteur), que la connexion ADSL n’ait pas été démarré/redémarré il y a moins de 15 minutes

– Enfin si tout est bon, on compare la vitesse de la connexion ADSL avec le mini en upload/download que l’on a indiqué, si on est en dessous, on reboot la Box

Ensuite, il ne reste plus qu’a l’exécuter en tache cron toutes les 5 minutes et le tour est joué.

Depuis que j’ai mis ça en place, j’ai toujours une connexion de bonne qualité.

Gawindx
Gawindx

Gawindx

Passionné de l'outil informatique dès mon plus jeune âge (j'ai commencé sur un MO5), je mets mes compétences au service de la communauté. Je "flirte" avec Linux depuis 2005 et j'ai complétement basculé dans le libre depuis plus de 3 ans.