Charl van Niekerk » Blog

Main

Latest

Archives

Powered by Blogger

PHP ADSL Account Switcher

Screenshot of my ADSL Account Switcher

I have multiple ADSL accounts and a Netgear ADSL router and eventually I just got irritated of moving between them, copying and pasting into that boring Netgear web interface. So I wrote a little script to do the work for me:

<?php
  // Handy library function for so-called "screen scraping" (I call it "HTML hacking")
  function extractSingle($text, $startDelim, $endDelim) {
    $start = strpos($text, $startDelim);
    if ($start === false) return false;
    $start += strlen($startDelim);
    $end = strpos($text, $endDelim, $start);
    if ($end === false) return false;
    return substr($text, $start, $end - $start);
  }
  
  // Load the configuration
  $config = new SimpleXMLElement(file_get_contents('adsl-config.xml'));
  
  // Change the account details if necessary
  if (isset($_REQUEST['username']) && isset($_REQUEST['password'])) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, "http://$config->host/setup.cgi");
    curl_setopt($curl, CURLOPT_USERPWD, "$config->user:$config->pass");
    curl_setopt($curl, CURLOPT_POSTFIELDS, 'DSLencapsulation=pppoe&pppoeName=' . urlencode($_REQUEST['username']) . '&pppoePasswd=' . urlencode($_REQUEST['password']) . '&pppoeService=&pppoeIdleTime=0&WAN_ipType=Dynamic&DNStype=Dynamic&natEnable=enabled&apply=Apply&h_DSLencapsulation=pppoe&wan_login=setup.cgi%3Fnext_file%3Dpppoe.htm&h_natEnable=enabled&h_WANlogin=enable&h_WAN_ipType=Dynamic&c4_pppoeip=&h_DNStype=Dynamic&c4_DNS1address=&c4_DNS2address=&runtest=&todo=save&this_file=pppoe.htm&next_file=basic.htm');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_exec($curl);
    curl_close($curl);
    header("Location: $_SERVER[REQUEST_URI]");
    exit;
  }
  
  // Get the current username / password from the router
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, "http://$config->host/setup.cgi?next_file=pppoe.htm");
  curl_setopt($curl, CURLOPT_USERPWD, "$config->user:$config->pass");
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  $ret = curl_exec($curl);
  curl_close($curl);
  $username = extractSingle($ret, '<input type="text" name="pppoeName" size="15" maxlength="63" value="', '"></td>');
  //$password = extractSingle($ret, '<input type="password" name="pppoePasswd" size="15" maxlength="63" value="', '"></td>');
  
  // Determine the title of the current adsl account
  $title = 'Unknown';
  foreach ($config->account as $account) {
    if ($account->username == $username) {
      $title = $account->title;
      break;
    }
  }
  
  header("Content-Type: text/html; charset=UTF-8");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <title>ADSL Account Switcher</title>
    <style type="text/css">
      body {
        padding: 40px;
        font: 0.8em / 1.6 verdana, arial, sans-serif;
        text-align: center;
      }
      h1 {
        font: 2em verdana, arial, sans-serif;
        letter-spacing: 2px;
      }
      h2 {
        margin: 40px 0 0 0;
        padding: 0;
        font: 1.4em verdana, arial, sans-serif;
        letter-spacing: 4px;
      }
    </style>
  </head>
  <body>
    <h1>ADSL Account Switcher</h1>
    <h2>Current Account</h2>
    <p>
      <strong>Account: <?php echo $title; ?></strong><br>
      Username: <?php echo htmlspecialchars($username); ?>
    </p>
    <h2>Switch To</h2>
    <?php foreach ($config->account as $account): ?>
      <form method="post" action="">
        <p>
          <input type="hidden" name="username" value="<?php echo htmlspecialchars($account->username); ?>">
          <input type="hidden" name="password" value="<?php echo htmlspecialchars($account->password); ?>">
          <input type="submit" value="<?php echo htmlspecialchars($account->title); ?>">
        </p>
      </form>
    <?php endforeach; ?>
  </body>
</html>

This is obviously just a hack for my personal use so sorry if it isn't too clean but I thought I should post it here anyway in case somebody can find any benefit out of it some way or the other. It might or might not work on your setup but the firmware version I am using here is V3.01.25

I actually want to transform the core functionality into an XML API but I don't know where I would use something like that.

Oh yes, and you'll also need the following configuration file (obviously you'll have to customise):

<adsl>
 <host>10.0.0.1</host>
 <user>admin</user>
 <pass>password</pass>
 <account>
  <title>Local (isp123)</title>
  <username>isp123@dsl512.isdsl.net</username>
  <password>fubarnoob</password>
 </account>
 <account>
  <title>International (isp234)</title>
  <username>isp234@dsl512.isdsl.net</username>
  <password>eishbahlol</password>
 </account>
</adsl>

2 Comments

Comment by Blogger tumbleweed on Monday, April 28, 2008 10:50:00 PM

If you have a server to run this on, why not put your router in bridged mode and do split-routing instead?

Comment by Blogger Charl van Niekerk on Tuesday, April 29, 2008 1:37:00 PM

Yeah that is my next experiment but because I have two ISDSL accounts I can't figure out which account it's using if I do a traceroute, so when I'm downloading an ISO from a mirror I'll have to find a smarter way to make sure it's going through the right account. The biggest pain is building the routing table correctly.

Post a Comment

Copyright © 2004-2008 Charl van Niekerk. All articles are released under the Creative Commons Attribution 2.5 South Africa licence, unless where otherwise stated.