Search code examples
c#htmlnetwork-programmingwebrequest

How to login to my router using c# application


I'm trying to get the list of the connected devices on my router. I can do it manually but I want a c# application to do it for me, so that I can monitor my network automatically.

What I already tried is to make a WebRequest to the URL of the router's page containing the devices with the code below:

string url = @"http://192.168.1.1/ui/dboard/homenet";
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.ContentType= "application/x-www-form-urlencoded";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("admin:admin"));

Stream stream = request.GetResponse().GetResponseStream();
StreamReader reader1 = new StreamReader(stream);
string response = reader1.ReadToEnd();

foreach (string el in response.Split('\n'))
{
    Console.WriteLine(el);
}

but the response that I get is the redirection to the router's login page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Cache-Control" content="no-cache" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="-1" />
    <link rel="SHORTCUT ICON" href="/images/shortcut.ico" />

    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Residential Gateway - D-Link</title>

    <link rel="stylesheet" href="/css/common.css" />
    <link rel="stylesheet" href="/css/theme.css" />

    <script type="text/javascript" src="/js/jquery.tools.min.js"></script>
    <script type="text/javascript" src="/js/common.js"></script>
    <script type="text/javascript" src="/js/headerMobile.js"></script>
    <script type="text/javascript">detectMobile();</script>

    <link rel='stylesheet' type='text/css' href='/css/login.css'/>
    <link rel='stylesheet' href='/css/custom.css'/>
    <script type='text/javascript'>detectMobile('login_m.css');</script>
    <script type='text/javascript'>detectMobile('custom_m.css');</script>
    <script type='text/javascript' src='/js/hmac-sha256.js'></script>
    <script type='text/javascript' src='/js/md5.js'></script>
    <script type='text/javascript' src='/js/md5_crypt.js'></script>
</head>
<body onresize="resize()" onscroll="resize()" onmouseup="resize()">
<div id="header">

<div id='btnClose'><button type='button' class='close' onclick='link_onclick(this); history.back()'/></div>

<img id="logo" src="/images/logo.png" />
</div>

<!--START content-->
<div id="content">

<form name="form" action="/ui/login" method="post" onsubmit="login_onsubmit();" autocomplete="off">
<div id="loginPanelBox">
<div id="navigationBarMobile">
        <ul>
<li>Login</li>
        </ul>
</div>


<div id="panelLogin" class="panel">
<label class="panel">
Login
</label>
<img class="panel" src="/images/Login16.png" />
<hr class="panel" />

<fieldset class="form">


<div class="formField" id="userName" help_tooltip="off">
        <label for="userName">Nome Utente:</label>
        <input type="text" name="userName" value="" />

</div>

<div class="formField" id="origUserPwd">
        <label for="origUserPwd">Password:</label>
        <div class="passwordField">

<input type="password" autocomplete="off" name="origUserPwd" value="" />

        </div>
</div>

I get the same result with a POST request, setting username and password as credentials like this:

request.Credentials = new NetworkCredential("admin", "admin");

but still, none useful result. I'm sure username and password are correct.

How can I successfully login and get the page I want? Router label is D-Link.


Solution

  • Thanks iSR5 for your suggestion of using browser debugger, it helped a lot.

    The core of my problem was an incomplete understanding of how web requests are managed by the router. A web request prompted from a web page (as the login page) is processed by cgi services running on the router. In particular, a service is called directly with an http request.

    For example, while logging on the router, click the "login button" triggers a call to a cgi service, in my case (I don't know if it works like this for every router label) username and password are passed as url arguments. Browser debugger shows the precise url.

    In order to avoid managing web pages a c# application has to make requests directly to cgi services.

    In addition to this it is necessary to manage cookies: after successfull login (connecting to cgi), response headers contains session cookies, for every further request made by c# application is necessary to add these cookies in request headers.