Reset router with Python script and Raspberry Pi

Recently, I have written an article Automatic router reboot device with Arduino where I have presented a simple Arduino–based solution to reset router periodically. Since this is not the best idea to reset it, even if it does not require resetting, I have applied purely software–based solution. As the title says I have used a Python script which runs on Raspberry Pi connected to a local network.

The idea

The Python script should check periodically if Internet is working and if it is not then it should reset the router. While checking if there is active Internet connection, resetting the router is not so easy. I will explain every step I have made to achieve the goal and so you would be able to reproduce the idea for yourself. I have set up network 192.168.1.0/24 to carry on the tests. Let’s start with the script.

Above code is pretty straightforward. It checks every timeToNextPing seconds the Internet connection via pinging Google DNS 8.8.8.8. If everything is as it should be it repeats the process. The problem arises when there is no Internet connection and testing IP 8.8.8.8 does not terminate successfully. The Python scripts tries numberOfRetries times to ping desired IP and waits timeBetweenRetries seconds between trials. After this it is safe to assume that there is some problem with the network. The above code offers a solution to this by rebooting the router. And since I like to keep tabs on everything the scripts logs all activity to a file.

Debugging router web page

Login

For interacting with the device package requests was used. It allows to interact with web pages. It is a HTTP library which makes handling requests and responses a lot easier!

Above code snippet is a general idea how it works. You define user and password and pass it to desired web page using POST method. One other thing is the Session it allows script to act like web browser and hold the history. In other word if you would like to reset router with i.e. http://192.168.0.1/reboot it would not work — the device the most probably would respond with “Access Denied”. By logging into the device you authorize yourself and by keeping session going you and the device know that you are allowed to reset the device or do any other kind of things. However, in more and more cases simple login will not work. Also above snipped makes a lot of assumptions about how validation for the device works. Address http://192.168.0.1/login is being used to pass the credentials but how do you know you should use http://192.168.0.1/login instead of http://192.168.0.1/secretlogin? Some reverse engineering and looking into code has to be done.

Most of web browsers has debug console which allows you to track all changes happening to web page. Using one of those and some deducing we can find out how the validation works for specific device. For this example Chrome web browser was used because it allow to keep history of the operation. You can start the debug console with Ctrl+Shift+I.

Before typing in router IP address go to Network tab and check Preserve log. But before typing anything to the login form let’s investigate HTML code a bit. Below you can see an example:

What you need to identify is how login name and password are named. Above those input fields are username and password. It is important to make a good identification because you have to use the exact names; otherwise the device will not understand. Ok! Let’s return to the Debug console. Type in username and password and hit login button. Something similar to below should appear:

There are a few thing about above figure. First you should identify which action you should look for. In this case it is login?form=login. After this you are almost there. I have marked three things, the last one will be attended to later on. First is the URL address you need to “request” with POST method. It was marked with red line. Now you can see this address is the same as in my Python script. The second thing is what actually was being sent over. It was marked with blue line — the Form Data. You can instantly notice that three fields were sent over: operation, username, password instead of two as it was shown in HTML code. That is why using Debug console is good thing to do. It can save a lot of time. The additional field was added with JavaScript script present on the web page. By using the Debug console you do not have to analyse the code and find out that below actually adds this field:

JavaScript

1

2

3

4

5

vardoLogin=function(){

loginForm.form("submit",{

"operation":"login"

},function(data,status,xhr){

vartoken=data.stok||(function(){

You can notice that the password value was awfully long. This is because a JavaScript is being used to encode plain password. You can either use it as it is or find a JavaScript function which is responsible for encoding the password. If you decide to go JavaScript way you can use Python to actually call JS function on some text — plain password. However, this approach would be useful if the encoded text would change. Presented approach is more like recording and replaying than actually interactive conversation between Python script and the router.

Reboot

Now, we should reboot the device. After that we could record something similar to:

Once again you have to find the right action. In this case it was: system?form=reboot. I have also marked with red line the most important thing — the URL address for rebooting device. As you can see it has something curious — an extra piece of information. It is a token. But wait … will it be the same every time? Unfortunately not! The thing with tokens is that they tend to change every time for a session. But there is one thing certain about tokens. You should receive one after successful login!

Retrieving token

Since it is in JSON format you need to translate it. You can use json Python library for decoding the data. But how do we know this is JSON format. Let’s go back to the first screen shoot, the one with login information, for a moment. Notice the text highlighted with green lines. It show the Response Header and inside it you can see that there is a field named Content-Type and it says it is json.

It is helpful to print the response to the output like this:

Python

1

print(data);

You will notice that there is a field named stock. This one carries the token!

All what was left to do is to parse a URL for reboot and call it like this:

That is all. You can tweak this solution to facilitate reboot of your own router.

Final remarks

The code was written in Python 3 and it was not tested with Python 2.

Also you can run this script automatically every time the system boots. Since I have a Raspberry Pi connected to my local network it monitoring the network. You can add below line to /etc/rc.local to make the script run an boot:

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.