Unitymedia

De WikiMar
Dreceres ràpides: navegació, cerca

Script to restart router Connect Box from Unitymedia. This router gets slower when it is not restarted for some time, and thus it improves connection to have a cron script to restart it once a day at 4am i.e.


<?php
# Original credit goes to: https://www.symcon.de/forum/threads/39200-Anwesenheitskontrolle-Unitymedia-Router-%28Connect-Box%29-IP-Tabelle-auslesen?p=377418

class UnitimediaRouter {
    /// you can do your setup here, or pass the configs on the go (as done in the example)
    var $ip = '';
    var $psw = '';
    var $debug = false;

    var $lastToken = false;
    var $sid = false;
    var $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36';

    // Construct: Pass ID and perform StartAction
    function __construct($ip = false){
        if ($ip){
            $this->ip = $ip;
        }
    }

    // Helper for performing CURL requests
    function httpRequest($url, $post = false, $header = false){
        $ch = curl_init('http://' . $this->ip.$url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);

        // Header
        if ($header){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }

        // Post
        if ($post){
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($post));
        }

        $result = curl_exec($ch);
        $info = curl_getinfo($ch);

        // get Response Header & Body
        $responseHeader = substr($result, 0, $info['header_size']-1);
        $body = substr($result, $info['header_size']);

        // Get Cookies from Response Header
        preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $responseHeader, $matches);
        $cookies = array();
        foreach($matches[1] as $item) {
            parse_str($item, $cookie);
            $cookies = array_merge($cookies, $cookie);
        }

        $resultFull = array(
            'info' => $info,
            'header' => $responseHeader,
            'body' => $body,
            'cookies' => $cookies,
            'result' => $result
        );

        if ($this->debug){
            print_r($resultFull);
        }
        return $resultFull;
    }

    // helper to transform a XML String to an assoc array
    static function xmlToArray($sXML){
        $oXml = simplexml_load_string($sXML);
        $json = json_encode($oXml);
        return json_decode($json,TRUE);
    }

    // helper to prepare an AJAX Call
    function headerForAjaxCall(){
        return array(
            'Accept: application/xml, text/xml, */*; q=0.01',
            'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie: ' . ($this->sid ? $this->sid.';' : '') . 'sessionToken=' . $this->lastToken, // Add SID (if available - after login) AND Token
            'User-Agent: '.$this->userAgent,
            'X-Requested-With: XMLHttpRequest'
        );
    }

    // every call changes the "sessionToken" which is needed for the next call
    function updateToken($result){
        if (isset($result['cookies']['sessionToken'])){
            $token = $result['cookies']['sessionToken'];
            if ($token){
                $this->lastToken = $token;
                return true;
            }
        }
        return false;
    }

    // ACTIONS

    // First thing to do:
    // Call login page to get a token to start with
    function start(){
        // header

        $header = array(
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'User-Agent: '.$this->userAgent,
        );

        // perform request
        $result = $this->httpRequest('/common_page/login.html', false , $header);

        // Update Token (changes every time)
        return $this->updateToken($result);
    }

    // Second:
    // Login with password to get a SID aswell
    function login($psw = false){
        if ($psw === false){
            $psw = $this->psw; // use default settings
        }
        // Post Data
        $post = array(
            'token' => $this->lastToken,
            'fun' => 15, // function 15 => login
            'Username' => 'NULL',
            'Password' => $psw
        );
        // header
        $header = $this->headerForAjaxCall();

        // perform request
        $result = $this->httpRequest('/xml/setter.xml', $post, $header);

        // Update Token (changes every time)
        if (!$this->updateToken($result)){
            return false;
        }

        // Valid response?
        if ($result['info']['http_code'] != 200 || !$result['body'] ){
            return false;
        }

        // Get Information (SID!) from response body
        $responseData = explode(';',$result['body']);
        if ($responseData[0] != 'successful'){ // Is either "successful" or "useridwrong" (or something like that)
            return false;
        }

        $this->sid = $responseData[1]; // save SID
        return true;
    }

    // last action: Logout (optional - but without it the router's webconsole is locked for other IPs (e.g. your browser) for some time)
    function logout(){
        // Post Data
        $post = array(
            'token' => $this->lastToken,
            'fun' => 16 // function 16 => logout
        );
        // header
        $header = $this->headerForAjaxCall();

        // perform request
        $result = $this->httpRequest('/xml/setter.xml', $post, $header);

        // Update Token (changes every time)
        if (!$this->updateToken($result)){
            return false;
        }

        return true;
    }

    // Get Connection Table as XML String (Login needed!)
    function getConnectionTableXML(){
        // Post Data
        $post = array(
            'token' => $this->lastToken,
            'fun' => 123 // function 123 => get IP Table
        );
        // header
        $header = $this->headerForAjaxCall();

        // perform request
        $result = $this->httpRequest('/xml/getter.xml', $post, $header);

        // Update Token (changes every time)
        if (!$this->updateToken($result)){
            return false;
        }

        // Valid response?
        if ($result['info']['http_code'] != 200 || !$result['body']){
            return false;
        }

        // get XML from responseBody
        $xml = trim($result['body']);
        return $xml;
    }




    function getPreRestart(){
        // Post Data
        $post = array(
            'token' => $this->lastToken,
            'fun' => 1 // function 1 => restart
        );
        // header
        $header = $this->headerForAjaxCall();

        // perform request
        $result = $this->httpRequest('/xml/getter.xml', $post, $header);

        // Update Token (changes every time)
        if (!$this->updateToken($result)){
            return false;
        }

        // Valid response?
        if ($result['info']['http_code'] != 200 || !$result['body']){
            return false;
        }

        // get XML from responseBody
        $xml = trim($result['body']);
        return $xml;
    }



    // Restart router (Login needed!)
    function getRestart(){
        // Post Data
        $post = array(
            'token' => $this->lastToken,
            'fun' => 8 // function 8 => confirm restart
        );
        // header
        $header = $this->headerForAjaxCall();

        // perform request
        $result = $this->httpRequest('/xml/setter.xml', $post, $header);

        // Update Token (changes every time)
        if (!$this->updateToken($result)){
            return false;
        }

        // Valid response?
        if ($result['info']['http_code'] != 200 || !$result['body']){
            return false;
        }

        // get XML from responseBody
        $xml = trim($result['body']);
        return $xml;
    }



}


// Usage Example

echo date('Y-m-d H:i:s') . "\n";

$oRouter = new UnitimediaRouter('192.168.0.1');
// $oRouter->debug = true;
if ($oRouter->start() == false){
    die('Error Start'); // e.g. Console is locked by an other user
}
if ($oRouter->login('YOURPASSWORD')){
    // get the table
//    $sXML = $oRouter->getConnectionTableXML();
//    if ($sXML){
//        // use the helper to get an array from XML String (you could also work with SimpleXML / DomXML ;)
//        $myConnections = UnitimediaRouter::xmlToArray($sXML);
//        // print_r($myConnections);
//        foreach ($myConnections["Ethernet"]["clientinfo"] as $value) {
//                echo "\t" . $value["IPv4Addr"] . "\t" . $value["MACAddr"]  . "\t" . $value["hostname"] ."\tETH" .  "\n";
//        }
//        foreach ($myConnections["WIFI"]["clientinfo"] as $value) {
//                echo "\t" . $value["IPv4Addr"] . "\t" . $value["MACAddr"]  . "\t" . $value["hostname"] . "\n";
//        }
  

    $sXML = $oRouter->getPreRestart();
    $sXML = $oRouter->getRestart();
    if ($sXML){
        // use the helper to get an array from XML String (you could also work with SimpleXML / DomXML ;)
        $myConnections = UnitimediaRouter::xmlToArray($sXML);
        print_r($myConnections);
    }

    // you should log out to free the web-console
    $oRouter->logout();
} else {
    die('Error Login'); // e.g. Password is wrong
}