März 3

Fritzbox 7430 auslesen mit Python – HTTP

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
##############################################################
#                                                            #
# Python prototype which logs on to a Fritz AVM 7430 and     #
# extracts all important DSL-Information                     #
#                                                            #
# original source code by framp at linux-tips-and-tricks.de  #
#                                                            #
# modified by me, Kloss Jan-Philip                           #
#                                                            #
# Python Version 2.7                                         #
#                                                            #
##############################################################

import httplib
from xml.dom import minidom
import hashlib
import re
import sys

USER_AGENT="Mozilla/5.0 (U; Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"

def getPage(server, sid, page, port):

    conn = httplib.HTTPConnection(server+':'+port)

    headers = { "Accept" : "application/xml",
        "Content-Type" : "text/plain",
        "User-Agent" : USER_AGENT}

    pageWithSid=page+"&sid="+sid
    conn.request("GET", pageWithSid, '', headers)
    response = conn.getresponse()
    data = response.read()
    if response.status != 200:
        print "%s %s" % (response.status, response.reason)
        print data
        sys.exit(0)
    else:
        return data

def loginToServer(server,password,port):

    conn = httplib.HTTPConnection(server+':'+port)

    headers = { "Accept" : "application/xml",
        "Content-Type" : "text/plain",
        "User-Agent" : USER_AGENT}

    initialPage='/login_sid.lua'
    conn.request("GET", initialPage, '', headers)
    response = conn.getresponse()
    data = response.read()
    if response.status != 200:
        print "%s %s" % (response.status, response.reason)
        print data
        sys.exit(0)
    else:
        theXml = minidom.parseString(data)
        sidInfo = theXml.getElementsByTagName('SID')
        sid=sidInfo[0].firstChild.data
        if sid == "0000000000000000":
            challengeInfo = theXml.getElementsByTagName('Challenge')
            challenge=challengeInfo[0].firstChild.data
            challenge_bf = (challenge + '-' + password).decode('iso-8859-1').encode('utf-16le')
            m = hashlib.md5()
            m.update(challenge_bf)
            response_bf = challenge + '-' + m.hexdigest().lower()
        else:
            return sid
        
    headers = { "Accept" : "text/html,application/xhtml+xml,application/xml",
        "Content-Type" : "application/x-www-form-urlencoded",
        "User-Agent" : USER_AGENT}

    loginPage="/login_sid.lua?&response=" + response_bf
    conn.request("GET", loginPage, '', headers)
    response = conn.getresponse()
    data = response.read()
    if response.status != 200:
        print "%s %s" % (response.status, response.reason)
        print data
        sys.exit(0)
    else:
        sid = re.search('<SID>(.*?)</SID>', data).group(1)
        if sid == "0000000000000000":
            print "ERROR - No SID received because of invalid password"
            sys.exit(0)
        return sid

server='IP'
password='passwort'
port='80'

sid=loginToServer(server,password, port)

if not sid:
    print "ERROR logging on"
    sys.exit(0)

page=getPage(server,sid,"/internet/dsl_stats_tab.lua?update=mainDiv",port)

for line in page.split('</tr>'):
    #DSLAM-Datenrate Max. Empfangsrate
    if 'DSLAM-Datenrate Max.' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('DSLAM-Datenrate Max. Empfangsrate',match.group(1))
    #DSLAM-Datenrate Max. Senderichtung
    if 'DSLAM-Datenrate Max.' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('DSLAM-Datenrate Max. Senderate',match.group(1))

    #DSLAM-Datenrate Min. Empfangsrate"
    if 'DSLAM-Datenrate Min.' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('DSLAM-Datenrate Min. Empfangsrate',match.group(1))
    #DSLAM-Datenrate Min. Senderate
    if 'DSLAM-Datenrate Min.' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('DSLAM-Datenrate Min. Senderate',match.group(1))

    #Leitungskapazität Empfangsrate
    if 'Leitungskapazität' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Leitungskapazität Empfangsrate',match.group(1))
    #Leitungskapazität Senderate
    if 'Leitungskapazität' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Leitungskapazität Senderate',match.group(1))

    #Aktuelle Empfangsdatenrate
    if 'Aktuelle Datenrate' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Aktuelle Empfangsdatenrate',match.group(1))
    #Aktuelle Sendedatenrate
    if 'Aktuelle Datenrate' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Aktuelle Sendedatenrate',match.group(1))

    #Empfangslatenz
    if 'Latenz' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Empfangslatenz',match.group(1))
    #Sendelatenz
    if 'Latenz' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Sendelatenz',match.group(1))

    #Empfangsleitungsdämpfung
    if 'Leitungsdämpfung' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Empfangsleitungsdaempfung',match.group(1))
    #Sendeleitungsdämpfung
    if 'Leitungsdämpfung' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Sendeleitungsdaempfung',match.group(1))

    #Fehlerrate FRITZ!Box
    if 'FRITZ!Box' in line:
        match = re.search('.*"c2">(\d+)',line)
        if match:
            print "%s: %s" % ('Sekunden mit Fehlern (ES)',match.group(1))
    #Fehlerrate FRITZ!Box
    if 'FRITZ!Box' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Sekunden mit vielen Fehlern (SES)',match.group(1))
    #Fehlerrate FRITZ!Box
    if 'FRITZ!Box' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Nicht behebbare Fehler (CRC) pro Sekunde',match.group(1))

    #Fehlerrate Vermittlungsstelle
    if 'Vermittlungsstelle' in line:
        match = re.search('.*"c2">(\d+)',line)
        if match:
            print "%s: %s" % ('Sekunden mit Fehlern (ES)',match.group(1))
    #Fehlerrate Vermittlungsstelle
    if 'Vermittlungsstelle' in line:
        match = re.search('.*"c3">(\d+)',line)
        if match:
            print "%s: %s" % ('Sekunden mit vielen Fehlern (SES)',match.group(1))
    #Fehlerrate Vermittlungsstelle
    if 'Vermittlungsstelle' in line:
        match = re.search('.*"c4">(\d+)',line)
        if match:
            print "%s: %s" % ('Nicht behebbare Fehler (CRC) pro Sekunde',match.group(1))

Das Programm bzw. daraus hervorgehende Plugins für Nagios und Cacti befinden sich unter Downloads.

Als Grundlage diente linux-tips-and-tricks.de.

 



Copyright 2019. All rights reserved.

Veröffentlicht3. März 2017 von JanPhilip in Kategorie "Allgemein

3 COMMENTS :

  1. By andreas on

    Hi
    ich würde gerne das Script verstehen. Leider bin ich neu was Python betrifft.
    Mir ist nicht ganz klar, wo ich den Server eingebe, ggf. einen Benutzer und das Passwort. Welches Passwort? kannst du mir verraten welche FritzBox Daten ich brauche?

    Ausserdem habe ich meine FritzBox per DynDNS einer Domain zugewiesen. ist IP = Domain? und wem ja FQD?

    Danke

    Antworten
    1. By JanPhilip (Beitrag Autor) on

      Hallo,

      ich würde es erstmal ohne DynDNS probieren und danach schauen ob man mit DynDNS die Login-Seite genauso erreichen kann. Bei DynDNS würde ich FQDN benutzen.
      Das Anmelden funktioniert mit den nachfolgenden Angaben im Quelltext:

      server='IP'
      password='passwort'
      port='80'

      IP wäre die IP der Fritzbox oder dein DynDNS
      Passwort ist das Gerätepasswort

      Ich hoffe ich konnte dir weiterhelfen, ansonsten müsste ich dein Vorhaben zu Hause nachstellen und das würde etwas Zeit in Anspruch nehmen.

      Antworten
      1. By Andreas on

        Danke.

        ich habe es wie folgt konfiguriert:

        server=’domain.de‘
        password=’geraetepw‘

        da bekomme ich als Rückmeldung:
        [Errno 113] No route to host

        eine Idee?

        Antworten

Schreibe einen Kommentar zu Andreas Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.